表格的DRY AngularJS控制器

时间:2014-02-06 18:35:53

标签: javascript angularjs dry

我在Web项目中使用AngularJS,我注意到几乎所有的表单控制器看起来都是一样的。与登录控制器(如下所示)和我的重置密码控制器$scope.loginForm.$invalid的唯一区别是$scope.resetForm.$invalid我将注入并使用ResetService而不是AuthService

angular.module('app').controller('LoginCtrl', function ($scope, AuthService) {

  // Form input data
  $scope.formData = {};

  // Are we in the middle of a submit process?
  $scope.busy = false;

  // Has the form been submitted yet?
  $scope.submitted = false;

  // Attempt to submit form via AJAX
  $scope.submit = function (actionUrl) {

    $scope.busy = true;
    $scope.submitted = true;

    // Invalid, activate form and return
    if ($scope.loginForm.$invalid) {
      $scope.busy = false;
      return;
    }

    // Submit data via AJAX
    AuthService.login(actionUrl, $scope.formData).error(function () {
      $scope.busy = false;
    });

  };

});

显然,这感觉不是很干,我假设有一个Angular特征或模式来提取这个类似的功能?

2 个答案:

答案 0 :(得分:1)

使用所有功能创建了FormCtrl控制器。可能因表单而异的2个项目是表单名称属性和用于表单的服务上的AJAX方法,因此我在$scope之后的函数中传递了这两个参数。然后我重构了代码,以便利用我传递给函数的那些变量。

LoginCtrl(或实现此目的的任何其他表单控制器)中唯一需要实现的是FormCtrl实例化并传递$scope,表单名称属性和最后是用于发出AJAX请求的服务方法。

<强>的login.html

<form ng-controller="LoginCtrl"
      ng-submit="submit('my-ajax-url.php')"
      name="loginForm">
  ...
</form>

<强> FormCtrl.js

angular.module('app').controller('FormCtrl', function ($scope, formName, ajaxFunction) {

  // Form input data
  $scope.formData = {};

  // Are we in the middle of a submit process?
  $scope.busy = false;

  // Has the form been submitted yet?
  $scope.submitted = false;

  // Attempt to submit form via AJAX
  $scope.submit = function (actionUrl) {

    $scope.busy = true;
    $scope.submitted = true;

    // Invalid, activate form and return
    if ($scope[formName].$invalid) {
      $scope.busy = false;
      return;
    }

    // Submit data via AJAX
    ajaxFunction(actionUrl, $scope.formData).error(function () {
      $scope.busy = false;
    });

  };

});

<强> LoginCtrl.js

angular.module('app').controller('LoginCtrl', function ($scope, $controller, AuthService) {

  // Instantiate form controller
  $controller('FormCtrl', {
    $scope: $scope,
    formName: 'loginForm',
    ajaxFunction: AuthService.login
  });

});

答案 1 :(得分:0)

看看我们在这里有什么:

angular.module('app').controller('LoginCtrl', FUNCTION)

您可以从工厂生成这些功能。

在angular中,您可以向函数添加$ inject变量,其值为要注入的名称数组。例如:

functionName.$inject = ['$rootScope'];

当通过angular调用该函数时,将注入$ rootScope。所以你可以务实地为服务注入服务。

angular.module('app')
    .controller(
        'LoginCtrl',
        ControllerFactory.createSubmitController(function(){}, ['$scope', 'AuthService'])
    )

createSubmitController内部,您可以创建一个包装函数,并注入所有必需的名称。使用您喜欢的功能扩充$scope,然后使用所有注入的名称以及增强的$scope调用第一个参数函数。

通过这种方式,您应该能够拥有相同的灵活性,并具有良好的默认行为基线。

您也可以在工厂中手动调用进样器,因此您只需要传递一个函数:

function($scope, AuthService)

这取决于你。

请参阅$inject Annotation