Pau*_*aul 4 angularjs angular-ngmodel
假设我想要一个指令,它接受用户在输入中键入的内容并将其转换为小写。
所以我想出了一个这样的指令(在这个 Plunker http://plnkr.co/edit/jnE3s8MRr1tFCX0WVYel?p=preview):
app.directive('lowerCaseInput', function() {
return {
restrict: 'E',
template:'<input ng-model="vm.input" />',
scope: {},
require: ['ngModel', 'lowerCaseInput'],
controller:function() {},
link: function(scope, el, attrs, ctrls) {
var ngModel = ctrls[0], vm = ctrls[1];
ngModel.$render = render;
// view-> model
ngModel.$parsers.push(function(value) {
return toLowerCase(value);
});
// model->view
ngModel.$formatters.push(function(value) {
return value;
});
function render() {
vm.input = ngModel.$viewValue;
}
// view -> model && model-> view
function toLowerCase(value) {
return value && value.toLowerCase();
}
scope.$watch('vm.input', function(newVal, oldVal) {
if(newVal !== oldVal)
ngModel.$setViewValue(newVal);
});
},
controllerAs: 'vm'
}
})
Run Code Online (Sandbox Code Playgroud)
但是,正如您在演示中看到的,模型值不会在初始传递中得到反映(全部变为小写),因为 setViewValue 从未被触发。对于我确实希望指令根据某些规则更改模型的情况,我是否应该遵循一般方法?
此外,我想避免在用户实际与之交互之前将控件变为脏控件,因此即使我确实让它调用 $setViewValue 并导致 $parsers 管道,我也希望它意识到用户实际上并没有与之交互(因此保持它的原始状态)。
这可能吗?如果是这样,关于它的一些最佳实践是什么(比如可以从 $format 调用 $setViewValue - 直接覆盖 ngModel?等等......
以下解决方案适用于我的(使用 Angular 1.4)
在更新视图值之前 y 只需保存对 $setDirty 函数的引用,并在 ngModelCtrl 中将其替换为空函数。设置 viewvalue 后,我恢复了原来的功能。
var tmp = ngModelController.$setDirty;
ngModelController.$setDirty = angular.noop;
ngModelController.$setViewValue(value);
ngModelController.$setDirty = tmp;
Run Code Online (Sandbox Code Playgroud)
这对我有用,因为我可以在我的自定义指令中设置默认值,并且输入字段和表单控制器都保持 $pristine。
当心:我没有使用自定义 ng-model-options。我没有尝试过,但我确定如果您使用自定义去抖动超时,则此解决方案对您不起作用,但我认为可以ngModelController.$setDirty = tmp;在去抖动时间到期后设法呼叫线路。
| 归档时间: |
|
| 查看次数: |
1965 次 |
| 最近记录: |