Tim*_*the 7 angularjs angularjs-validation
我正在开发一个应用程序,可以在用户更改内容时自动保存更改,例如输入字段的值.我已经编写了一个autosave指令,该指令被添加到应该自动触发保存事件的所有表单字段中.
模板:
<input ng-model="fooCtrl.name" autosave>
<input ng-model="fooCtrl.email" autosave>
Run Code Online (Sandbox Code Playgroud)
指示:
.directive('autosave', ['$parse', function ($parse) {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, element, attrs, ngModel) {
function saveIfModelChanged () {
// save object containing name and email to server ...
}
ngModel.$viewChangeListeners.push(function () {
saveIfModelChanged();
});
}
};
}]);
Run Code Online (Sandbox Code Playgroud)
到目前为止,这一切对我来说都很好.但是,当我在混合中添加验证时,例如验证输入字段是有效的电子邮件地址,undefined一旦viewValue更改为无效的电子邮件地址,modelValue就会设置为.
我想要做的是:记住最后一个有效的modelValue并在autosaving时使用它.如果用户更改的电子邮件地址是无效的,对象含有name与email仍应保存到服务器.使用当前有效name和最后有效email.
我开始时保存最后一个有效的modelValue,如下所示:
添加验证的模板:
<input type="email" ng-model="fooCtrl.name" autosave required>
<input ng-model="fooCtrl.email" autosave required>
Run Code Online (Sandbox Code Playgroud)
保存lastModelValue的指令:
.directive('autosave', ['$parse', function ($parse) {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, element, attrs, ngModel) {
var lastModelValue;
function saveIfModelChanged () {
// remeber last valid modelValue
if (ngModel.$valid) {
lastModelValue = ngModel.$modelValue;
}
// save object containing current or last valid
// name and email to server ...
}
ngModel.$viewChangeListeners.push(function () {
saveIfModelChanged();
});
}
};
}]);
Run Code Online (Sandbox Code Playgroud)
我的问题是,如何lastModelValue在保存时使用,但在视图中保留无效值?
编辑:
正如下面Jugnu所建议的那样,另一种可能性是在验证器中包装和操作构建.
我试着跟随:包装所有现有的验证器并记住最后一个有效值,如果验证失败则恢复它:
Object.keys(ngModel.$validators).forEach(function(validatorName, index) {
var validator = ngModel.$validators[validatorName];
ngModel.$validators[validatorName] = createWrapper(validatorName, validator, ngModel);
});
function createWrapper(validatorName, validator, ngModel){
var lastValid;
return function (modelValue){
var result = validator(modelValue);
if(result) {
lastValid = modelValue;
}else{
// what to do here? maybe asign the value like this:
// $parse(attrs.ngModel).assign(scope, lastValid);
}
return result;
};
}
Run Code Online (Sandbox Code Playgroud)
但我不知道如何继续采用这种方法.我可以在没有AngularJS的情况下设置模型值并尝试验证新设置的值吗?
我创建了一个简单的指令,用作ng-model指令的包装器,并将始终保留最新的有效模型值。它称为valid-ng-model ,应该在您想要获得最新有效值的地方替换ng-model的使用。
我在这里创建了一个示例用例,希望您会喜欢。欢迎任何改进的想法。
这是valid-ng-model指令的实现代码。
app.directive('validNgModel', function ($compile) {
return {
terminal: true,
priority: 1000,
scope: {
validNgModel: '=validNgModel'
},
link: function link(scope, element, attrs) {
// NOTE: add ngModel directive with custom model defined on the isolate scope
scope.customNgModel = angular.copy(scope.validNgModel);
element.attr('ng-model', 'customNgModel');
element.removeAttr('valid-ng-model');
// NOTE: recompile the element without this directive
var compiledElement = $compile(element)(scope);
var ngModelCtrl = compiledElement.controller('ngModel');
// NOTE: Synchronizing (inner ngModel -> outside valid model)
scope.$watch('customNgModel', function (newModelValue) {
if (ngModelCtrl.$valid) {
scope.validNgModel = newModelValue;
}
});
// NOTE: Synchronizing (outside model -> inner ngModel)
scope.$watch('validNgModel', function (newOutsideModelValue) {
scope.customNgModel = newOutsideModelValue;
});
}
};
});
Run Code Online (Sandbox Code Playgroud)
编辑:没有隔离范围的指令实现:Plunker。
| 归档时间: |
|
| 查看次数: |
1485 次 |
| 最近记录: |