私はAngularJSのv1.2.0 rc2を使用しており、複数のコントローラに共通の機能を提供する最も良い方法が何であるかを知りたいと考えています。
Iモデル編集私はすべてのコントローラで使用する次の検証機能があります。
$scope.canSave = function (formController) {
return formController.$dirty && formController.$valid;
};
$scope.validationClasses = function (modelController) {
return {
'has-error': modelController.$invalid && modelController.$dirty,
'has-success': modelController.$valid && modelController.$dirty
};
};
私は私のコントローラを維持したいが、次のように私は工場を定義したドライ:
angular.module('myModule', [])
.factory('validationFactory', [function() {
return {
validationClasses: function (modelController) {
return {
'has-error': modelController.$invalid && modelController.$dirty,
'has-success': modelController.$valid && modelController.$dirty
};
},
isFormValid: function (formController) {
return formController.$dirty && formController.$valid;
}
};
}]);
は当初、私は次のようにそれを必要とコントローラーに工場を混入:
$scope.canSave = validationFactory.isFormValid;
$scope.validationClasses = validationFactory.validationClasses;
しかし、私は次のように私は、モジュールのrunメソッドで$ rootScopeにそれらを追加することができます実現:
angular.module('myModule', [])
.run([
'$rootScope',
'validationFactory',
function ($rootScope, validationFactory) {
$rootScope.canSave = $rootScope.canUpdate = validationFactory.isFormValid;
$rootScope.validationClasses = validationFactory.validationClasses;
}]);
今、彼らは無差別にすべてのコントローラで利用可能であり、行うには少ない配線アップがあります。次のように
機能がビューテンプレートで使用されています
<form name="questionForm" novalidate>
<div class="form-group" ng-class="validationClasses(questionForm.question)">
<label for="questionText" class="control-label">Text</label>
<input type="text" ng-model="question.text" name="question"
id="questionText" class="form-control" required/>
<span ng-show="questionForm.question.$error.required"
class="help-block">Question text is required</span>
</div>
...
<div class="form-group" ng-switch on="action">
<button type="button" ng-switch-when="New" ng-click="save()"
ng-disabled="!canSave(questionForm)"
class="btn btn-primary">Save</button>
<button type="button" ng-switch-default ng-click="update()"
ng-disabled="!canUpdate(questionForm)"
class="btn btn-primary">Update</button>
<button type="button" ng-click="cancel()"
class="btn btn-default">Cancel</button>
</div>
</form>
私の質問は以下のとおりです。
- 私は$ rootScopeに共通の機能を追加することは避けるべき?もしそうなら、落とし穴は何ですか?
- 必要な場合にのみ共通の機能を混在させる方が良いでしょうか?
- 同じ結果を達成するためのより良い方法はありますか?
ソリューション更新
は
私はそれについての異臭を持っていた$ rootScopeに機能を追加するのではなく、カスタムディレクティブを使用することにしました。
私は、カスタムので、マークアップは次のようになりますvalidation-class-for="<input.name>"
とdisabled-when-invalid
属性作成:
<div class="form-group" validation-class-for="question">
<label for="questionText" class="control-label">Text</label>
<input type="text" ng-model="question.text" name="question"
id="questionText" class="form-control" required/>
<span ng-show="questionForm.question.$error.required"
class="help-block">Question text is required</span>
</div>
<button type="button" ng-click="save()" disabled-when-invalid
class="btn btn-primary">Save</button>
ディレクティブは単にフォーム祖先を必要とし、状態を判断するための機能を見て。
angular.module('myModule', [])
.directive('validationClassFor', function() {
return {
require: '^form',
link: function (scope, element, attributes, formController) {
scope.$watch(function() {
var field = formController[attributes.validationClassFor];
if (field.$invalid && field.$dirty) {
element.removeClass('has-success').addClass('has-error');
} else if (field.$valid && field.$dirty) {
element.removeClass('has-error').addClass('has-success');
} else {
element.removeClass('has-error').removeClass('has-success');
}
});
}
};
})
.directive('disabledWhenInvalid', function() {
return {
require: '^form',
link: function (scope, element, attributes, formController) {
scope.$watch(function() {
return formController.$dirty && formController.$valid;
}, function (value) {
element.prop('disabled', !value);
});
}
};
});
これで、検証工場は必要ありません。
私は、保存/更新ボタンが無効になっているかどうか、およびフォームグループに適用されているCSSクラスを制御する機能を使用しています。 – gwhn