我正在开发一个应用程序,可以在用户更改内容时自动保存更改,例如输入字段的值.我编写了一个自动保存指令,该指令被添加到应自动触发保存事件的所有表单字段中.
模板:
<input ng-model="fooCtrl.name" autosave> <input ng-model="fooCtrl.email" autosave>
指示:
.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(); }); } }; }]);
到目前为止,这一切对我来说都很好.但是,当我在混合中添加验证时,例如将输入字段验证为有效的电子邮件地址,只要viewValue更改为无效的电子邮件地址,modelValue就会设置为undefined.
我想要做的是:记住最后一个有效的modelValue并在autosaving时使用它.如果用户将电子邮件地址更改为无效,则包含名称和电子邮件的对象仍应保存到服务器.使用当前有效名称和最后一封有效电子邮件.
我开始时保存最后一个有效的modelValue,如下所示:
添加验证的模板:
<input type="email" ng-model="fooCtrl.name" autosave required> <input ng-model="fooCtrl.email" autosave required>
保存lastModelValue的指令:
.directive('autosave',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(); }); } }; }]);
我的问题是,如何在保存时使用lastModelValue,但在视图中保留无效值?
编辑:
另一种可能性,as suggested by Jugnu below,将包装和操纵验证器中的构建.
我试着跟随:包装所有现有的验证器并记住最后一个有效值,如果验证失败则恢复它:
Object.keys(ngModel.$validators).forEach(function(validatorName,index) { var validator = ngModel.$validators[validatorName]; ngModel.$validators[validatorName] = createWrapper(validatorName,validator,ngModel); }); function createWrapper(validatorName,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; }; }
但我不知道如何继续采用这种方法.我可以在没有AngularJS的情况下设置模型值并尝试验证新设置的值吗?
我创建了一个简单的指令,作为ng-model指令的包装器,并始终保持最新的有效模型值.它被称为valid-ng-model,应该在您想要拥有最新有效值的地方替换ng-model的使用.
原文链接:https://www.f2er.com/angularjs/240347.html我已经创建了一个示例用例here,我希望你会喜欢它.欢迎任何改进的想法.
这是valid-ng-model指令的实现代码.
app.directive('validNgModel',function ($compile) { return { terminal: true,priority: 1000,scope: { validNgModel: '=validNgModel' },link: function link(scope,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; }); } }; });
Edit: directive implementation without isolate scope: 07001.