アプリケーション全体で再利用される一般的に再利用されるフォーム入力のセットがあるため、それらをカスタム ディレクティブにカプセル化しようとしています。ディレクティブに を設定しngModel
、メイン ディレクティブ内のいくつかの異なる入力 (そのうちのいくつかはディレクティブ自体) で編集できるように分割したいと考えています。
同時に、適切なメッセージとスタイルを表示できるように、フォームの検証結果をチェーンを介して親フォームに渡す必要があります。
これを実装する最も簡単で最も慣用的な方法は何ですか?
これらの (簡略化された) テンプレートは、私が何をしようとしているかの例を示しているはずです...
OuterTemplate.html
<form name="outerForm">
<my-directive
ng-model="ctrl.myComplexModel"
name="myDirectiveInstance"
custom-required="ctrl.EnableValidateOne"
toggle-another-validation="ctrl.EnableValidateTwo">
</my-directive>
<div ng-messages="outerForm.myDirectiveInstance.$error">
<ng-message when="customRequired">This is required.</ng-message>
<ng-message when="anotherValidation">This is required.</ng-message>
<ng-message when="innerValidationOne">Something wrong with field 1.</ng-message>
<ng-message when="innerValidationTwo">Something wrong with field 2.</ng-message>
<ng-message when="innerValidationThree">Something wrong with field 3.</ng-message>
<!-- etc... -->
</div>
</form>
myDirectiveTemplate.html
<div ng-form="myDirectiveForm">
<div ng-class="{'has-error': myDirectiveForm.fieldOne.$invalid}">
<ui-select
ng-model="model.fieldOne"
name="fieldOne"
required>
</ui-select>
</div>
<div ng-class="{'has-error': myDirectiveForm.fieldTwo.$invalid}">
<input
type="number"
ng-model="model.fieldTwo"
name="fieldTwo"
ng-pattern="directiveCtrl.someRegEx"
ng-required="directiveCtrl.fieldTwoIsRequired">
</div>
<!-- etc... -->
</div>
現時点では、myDirectiveForm
との両方myDirectiveInstance
が のプロパティとして公開されていますouterForm
FormController
。私はこのディレクティブをブラック ボックスにしたいと思っているので、myDirectiveForm
直接アタッチしているという事実はouterForm
私を悩ませ、私が何か間違ったことをしていることを示しているようです。
これが私のディレクティブ定義が今どのように見えるかです。
myDirective.js
app.directive('myDirective', function() {
return {
restrict: 'E',
template: 'myDirectiveTemplate.html',
controller: 'MyDirectiveCtrl',
scope: {
model: '=ngModel',
customRequired: '=?',
toggleAnotherValidation: '=?'
},
require: 'ngModel',
link: function(scope, iElem, iAttrs, ngModelController) {
// Black-box the internal validators
// Custom validator to avoid conflicts with ngRequired
ngModelController.$validators.customRequired = function(modelValue, viewValue) {
if(!scope.customRequired)
return true;
// On first digest the field isn't registered on the form controller yet
if(angular.isUndefined(scope.myDirectiveForm.fieldOne))
return true;
return !scope.myDirectiveForm.fieldOne.$error.required;
};
ngModelController.$validators.anotherValidation = function(modelValue, viewValue) {
if(!scope.anotherValidation)
return true;
return scope.passesBusinessRule();
};
ngModelController.$validators.innerValidationOne = function(modelValue, viewValue) {
if(!scope.anotherValidation)
return true;
if(angular.isUndefined(scope.myDirectiveForm.fieldTwo))
return true;
return !scope.myDirectiveForm.fieldTwo.$error.pattern;
};
/* etc... */
// Deep-watching model so that validations will trigger on updates of properties
scope.$watch('model', function() {
ngModelController.$validate();
}, true);
}
};
});