[英]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)
随你(由你决定。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.