Angular ng-required 无法使用自定义指令
Angular ng-required not working with custom directive
我正在使用 Angularjs 版本 1.5 来验证我表单中的输入。
- ng-required 用于验证所需的所有输入
但是,它不适用于呈现组合的自定义指令。该组合根据传递给它的名为 'listId' 的参数检索项目。然后,它使用 ng-repeat 迭代 'lookupItems'。我猜有些东西不见了,比如 ngModel。为什么以及如何实施?
组合指令:
app.directive('combo', function($http) {
return {
restrict: 'AE',
template: '<div class="input-group"> <select ng-model="selectedItem">' +
'<option ng-repeat="option in lookupItems" value={{option.ListValueID}}>{{option.Translation.Value}}</option></select>' +
' {{selectedItem}} </div>',
replace: true,
scope: {
listId: '=',
defaultItem: '=',
selectedItem: '='
},
controller: function($scope) {
$http({
method: 'GET',
url: '/home/listvalues?listid=' + $scope.listId
}).then(function(response) {
$scope.lookupItems = response.data;
}, function(error) {
alert(error.data);
});
},
link: function(scope, element, attrs) {}
};
});
html 视图: 正在迭代包含要呈现的控件类型的属性,然后将其设置 ng-required 为基于 [=36 的布尔值=] 这是真的。
<form name="profileAttributesForm" ng-controller="metadataCtrl" class="my-form">
<div ng-repeat="a in attributes">
<div ng-if="a.DataType == 1">
<input type="text" name="attribute_{{$index}}" ng-model="a.Value" ng-required="a.Required" />
<span ng-show="profileAttributesForm['attribute_{{$index}}'].$invalid">Enter a Text</span> text : {{a.Value}}
</div>
<div ng-if="a.DataType == 4">
<div combo list-id="a.LookUpList" name="attribute_{{$index}}" selected-item="a.Value" ng-required="a.Required"></div>
<span ng-show="profileAttributesForm['attribute_{{$index}}'].$invalid">lookup Required</span> Value from lookup: {{a.Value}}
</div>
</div>
</form>
属性示例 ($scope.attributes) 在表单中迭代, 我提供它只是为了说明目的:
[{
"AttributeID": 1,
"DataType": 4,
"NodeID": 0,
"Name": "Name",
"Description": null,
"LookUpList": 1,
"SortAscending": false,
"Required": true,
"DefaultValue": "1",
"Order": 1,
"Value": ""
}, {
"AttributeID": 3,
"DataType": 1,
"NodeID": 0,
"Name": "Job Title",
"Description": null,
"LookUpList": 0,
"SortAscending": false,
"Required": true,
"DefaultValue": null,
"Order": 2,
"Value": ""
}, {
"AttributeID": 4,
"DataType": 1,
"NodeID": 0,
"Name": "Email",
"Description": null,
"LookUpList": 0,
"SortAscending": false,
"Required": true,
"DefaultValue": null,
"Order": 3,
"Value": ""
}]
为了 ngRequired to set its validator it requires ngModel to be set on the same element in order to get NgModelController 从它,否则它只会设置所需的属性打开或关闭而不影响父窗体。
表单状态($pristine、$valid 等)不是由它的 HTML 决定的,而是由注册的 NgModelControllers 决定的。当在表单内链接 ngModel 时,会自动添加控制器。
- 例如,此
<input required type="text">
不会影响表单的有效性,即使它是必需的,因为它没有分配给它的 ngModel。
- 但是这个
<div ng-model="myDiv" required></div>
会影响它,因为它是必需的并且已为其分配了 ngModel。
对于你的情况,我看到了两个解决方案:
- 最简单的: 将 ngRequired 移到
combo
中,并将其添加到与 ngModel 相同的元素上;为此,您还需要添加一个新的范围变量,例如isRequired
复杂的: 将 require: 'ngModel'
添加到您的指令并进行适当的更改以使其工作。 这样您将拥有更大的控制力和灵活性。例如,如果以后要将 ngModelOptions 添加到 combo
,您会怎么做?如果您不实施此解决方案,则必须手动添加。
您可以先阅读 What's the meaning of require: 'ngModel'? - it's an awesome question/answer which contains different examples. For a more in-depth explanation, have a look at Using NgModelController with Custom Directives. As a side note, in Angular 1.5 they improved the syntax of require
- see $onInit and new "require" Object syntax in Angular components。
我正在使用 Angularjs 版本 1.5 来验证我表单中的输入。
- ng-required 用于验证所需的所有输入
但是,它不适用于呈现组合的自定义指令。该组合根据传递给它的名为 'listId' 的参数检索项目。然后,它使用 ng-repeat 迭代 'lookupItems'。我猜有些东西不见了,比如 ngModel。为什么以及如何实施?
组合指令:
app.directive('combo', function($http) {
return {
restrict: 'AE',
template: '<div class="input-group"> <select ng-model="selectedItem">' +
'<option ng-repeat="option in lookupItems" value={{option.ListValueID}}>{{option.Translation.Value}}</option></select>' +
' {{selectedItem}} </div>',
replace: true,
scope: {
listId: '=',
defaultItem: '=',
selectedItem: '='
},
controller: function($scope) {
$http({
method: 'GET',
url: '/home/listvalues?listid=' + $scope.listId
}).then(function(response) {
$scope.lookupItems = response.data;
}, function(error) {
alert(error.data);
});
},
link: function(scope, element, attrs) {}
};
});
html 视图: 正在迭代包含要呈现的控件类型的属性,然后将其设置 ng-required 为基于 [=36 的布尔值=] 这是真的。
<form name="profileAttributesForm" ng-controller="metadataCtrl" class="my-form">
<div ng-repeat="a in attributes">
<div ng-if="a.DataType == 1">
<input type="text" name="attribute_{{$index}}" ng-model="a.Value" ng-required="a.Required" />
<span ng-show="profileAttributesForm['attribute_{{$index}}'].$invalid">Enter a Text</span> text : {{a.Value}}
</div>
<div ng-if="a.DataType == 4">
<div combo list-id="a.LookUpList" name="attribute_{{$index}}" selected-item="a.Value" ng-required="a.Required"></div>
<span ng-show="profileAttributesForm['attribute_{{$index}}'].$invalid">lookup Required</span> Value from lookup: {{a.Value}}
</div>
</div>
</form>
属性示例 ($scope.attributes) 在表单中迭代, 我提供它只是为了说明目的:
[{
"AttributeID": 1,
"DataType": 4,
"NodeID": 0,
"Name": "Name",
"Description": null,
"LookUpList": 1,
"SortAscending": false,
"Required": true,
"DefaultValue": "1",
"Order": 1,
"Value": ""
}, {
"AttributeID": 3,
"DataType": 1,
"NodeID": 0,
"Name": "Job Title",
"Description": null,
"LookUpList": 0,
"SortAscending": false,
"Required": true,
"DefaultValue": null,
"Order": 2,
"Value": ""
}, {
"AttributeID": 4,
"DataType": 1,
"NodeID": 0,
"Name": "Email",
"Description": null,
"LookUpList": 0,
"SortAscending": false,
"Required": true,
"DefaultValue": null,
"Order": 3,
"Value": ""
}]
为了 ngRequired to set its validator it requires ngModel to be set on the same element in order to get NgModelController 从它,否则它只会设置所需的属性打开或关闭而不影响父窗体。
表单状态($pristine、$valid 等)不是由它的 HTML 决定的,而是由注册的 NgModelControllers 决定的。当在表单内链接 ngModel 时,会自动添加控制器。
- 例如,此
<input required type="text">
不会影响表单的有效性,即使它是必需的,因为它没有分配给它的 ngModel。 - 但是这个
<div ng-model="myDiv" required></div>
会影响它,因为它是必需的并且已为其分配了 ngModel。
对于你的情况,我看到了两个解决方案:
- 最简单的: 将 ngRequired 移到
combo
中,并将其添加到与 ngModel 相同的元素上;为此,您还需要添加一个新的范围变量,例如isRequired
复杂的: 将
require: 'ngModel'
添加到您的指令并进行适当的更改以使其工作。 这样您将拥有更大的控制力和灵活性。例如,如果以后要将 ngModelOptions 添加到combo
,您会怎么做?如果您不实施此解决方案,则必须手动添加。您可以先阅读 What's the meaning of require: 'ngModel'? - it's an awesome question/answer which contains different examples. For a more in-depth explanation, have a look at Using NgModelController with Custom Directives. As a side note, in Angular 1.5 they improved the syntax of
require
- see $onInit and new "require" Object syntax in Angular components。