[英]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.