如何使用ngModel手动重新运行angularjs指令中的格式化程序链?

时间:2015-07-12 13:32:59

标签: javascript angularjs angularjs-directive angular-ngmodel html-input

Angular.js ngModel能够声明parsersformatters的链。可以在great answer to 'How to do two-way filtering in angular.js?'

找到更多详细信息

现在只有在ngModel更新时才会运行格式化程序链。 因此,如果您有第二个影响viewValue的输入参数(在其中一个格式化程序中使用),则不会触发View的更新。 类似的,我发现ngModel只使用一个简单的$ watch - 所以如果你的模型是一个集合/对象,它将不会触发子元素被更改。

为ngModel实施深度监视的最佳方法是什么 -
或者注意应该重新运行格式化程序链的附加参数?

还有其他类似的问题:
Angularjs: how to “rerun” $formatters when some setting is changed?

1 个答案:

答案 0 :(得分:4)

目前没有直接api来调用内部格式化程序链。 这有一个github feature request。作为解决方法,您只需复制内部代码:

function runFormatters(ctrl){
    // this function is a copy of the internal formatter running code.
    // https://github.com/angular/angular.js/issues/3407#issue-17469647

    var modelValue = ctrl.$modelValue;

    var formatters = ctrl.$formatters;
    var idx = formatters.length;

    var viewValue = modelValue;

    while (idx--) {
        viewValue = formatters[idx](viewValue);
    }

    if (ctrl.$viewValue !== viewValue) {
        ctrl.$viewValue = ctrl.$$lastCommittedViewValue = viewValue;
        ctrl.$render();

        ctrl.$$runValidators(modelValue, viewValue, angular.noop);
    }

}

this Plunker演示了与手表结合用于其他参数的用法:

// deepwatch all listed attributes
scope.$watch(
    function(){
        return [scope.extraThingToWatchFor, scope.someOther];
    },
    function() {
        console.log("\t runformatters()");
        runFormatters();
    },
    true
);

this is a second Plunker演示ngModel上的深度计

// deepwatch ngModel
scope.$watch(
    function(){
        return ngModelCtrl.$modelValue;
    },
    function(newData) {
        runFormatters(ngModelCtrl);
    },
    true
);