我在ng-repeat块中有几个输入字段,用户可以使用按钮添加和删除字段。指令用于标记模糊上的无效字段。
我的问题是: 当我在控制器中向模型添加新字段时,一切正常。视图已更新,并再次调用该指令以处理输入字段上的错误。 但是当我从模型中删除Fields时,视图会更新,但指令不会运行。渲染ng-repeat时,函数将绑定到字段的blur事件。 (inputNgEl.bind)。当用户从列表中删除字段时,例如,第2个字段为4时,其余字段将获得新名称,因此必须再次绑定该函数。这就是为什么我需要指令在一个人被移除后再次运行。
我的演示代码:http://plnkr.co/edit/EBggptFsMFld2fMfzS83?p=preview
您可以在控制台中看到添加新字段时如何调用该指令,但在删除它时则不能。
我需要的是一种在控制器的removePersonFields函数中手动触发指令的方法,或者另一种更优雅的解决方案。这可能吗?
这是HTML:
<form novalidate name="form">
<div ng-repeat="person in persons" >
<div class="form-group" show-errors errorfieldindex="{{$index}}">
<label class="control-label">Name ({{'name_'+$index}})</label>
<input ng-model="person.name" name="name_{{$index}}" required class="form-control">
<span ng-if="form['name_'+$index].$error.required" class="help-block">Name invalid.</span>
</div>
<div class="form-group" show-errors errorfieldindex="{{$index}}">
<label class="control-label">Mail ({{'email_'+$index}})</label>
<input type="email" ng-model="person.email" name="email_{{$index}}" required class="form-control">
<span ng-if="form['email_'+$index].$error.required" class="help-block">Email required.</span>
<span ng-if="form['email_'+$index].$error.email" class="help-block">EMail invalid.</span>
</div>
<div class="btn-group">
<button type="button" class="btn btn-default" ng-click="removePersonFields($index)" ng-show="persons.length > 1">remove</button>
<button type="button" class="btn btn-default" ng-click="addPersonFields()">add</button>
</div>
</div>
</form>
相应的控制器:
app.controller('MainCtrl', function($scope) {
$scope.init = function() {
$scope.persons = [{name: 'User One', email: 'aaa.bbb@ccc.org'},
{name: 'User Two', email: 'ddd.eee@fff.org'}];
}
$scope.addPersonFields = function() {
console.log("add person row");
$scope.persons.push( {name: '', email: ''});
}
$scope.removePersonFields = function(index) {
console.log("remove person row");
$scope.persons.splice(index,1);
// the view is updated after the splice, but the directive does not run.
}
$scope.init();
});
每个输入字段都有一个名称,其中包含循环的当前索引。我在指令'show-errors'中使用此名称,以在字段失去焦点时分配和删除css类。该类仅用于隐藏错误消息,直到用户离开输入字段。
指令'showErrors':
app.directive('showErrors', function() {
return {
restrict: 'A',
require: '^form',
scope: {
errorfieldindex : '@'
},
link: function (scope, el, attrs, formCtrl) {
console.log("showErrors - link!");
// find the text box element, which has the 'name' attribute
var inputEl = el[0].querySelector("[name]");
// convert the native text box element to an angular element
var inputNgEl = angular.element(inputEl);
// get the name on the text box so we know the property to check
// on the form controller
var inputName = inputNgEl.attr('name');
if(typeof inputName != 'undefined') {
console.log("inputName: " + inputName);
var errorFieldIndex = scope.errorfieldindex;
if(typeof errorFieldIndex != 'undefined') {
console.log("errorFieldIndex: " + errorFieldIndex);
if(inputName.indexOf("{{$index}}") > 0) {
console.log("replace {{$index}} with " + errorFieldIndex);
inputName = inputName.replace("{{$index}}", errorFieldIndex);
}
}
// only apply the has-error class after the user leaves the text box
inputNgEl.bind('blur', function() {
console.log("bind Blur-event on element: " + inputName);
el.toggleClass('has-error', formCtrl[inputName].$invalid);
});
}
}
}
});