繁体   English   中英

表格的DRY AngularJS控制器

[英]DRY AngularJS Controllers for forms

我在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特征或模式来提取这个类似的功能?

使用所有功能创建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
  });

});

看看我们在这里有什么:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM