入力フィールドの値など、ユーザーが何かを変更したときに変更を自動的に保存するアプリケーションに取り組んでいます。autosave
保存イベントを自動的にトリガーする必要があるすべてのフォーム フィールドに追加されるディレクティブを作成しました。
テンプレート:
<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();
});
}
};
}]);
これまでのところ、これはすべてうまくいきます。ただし、入力フィールドが有効な電子メール アドレスであることを検証するなど、検証をミックスに追加すると、undefined
viewValue が無効な電子メール アドレスに変更されるとすぐに modelValue が設定されます。
私がやりたいことはこれです: 最後の有効なモデル値を記憶し、自動保存時にこれを使用します。ユーザーが電子メール アドレスを無効に変更した場合でもname
、 とを含むオブジェクトemail
はサーバーに保存する必要があります。現在の validname
と最後の valid を使用しますemail
。
次のように、最後の有効な modelValue を保存することから始めました。
検証が追加されたテンプレート:
<input type="email" ng-model="fooCtrl.name" autosave required>
<input ng-model="fooCtrl.email" autosave required>
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();
});
}
};
}]);
私の質問は、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;
};
}
しかし、このアプローチを継続する方法もわかりません。AngularJS を起動せずにモデル値を設定し、新しく設定された値を検証することはできますか?