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

Posted

技术标签:

【中文标题】如何使用 ngModel 在 angularjs 指令中手动重新运行格式化程序链?【英文标题】:How to manually rerun formatter chain in angularjs directive with ngModel? 【发布时间】:2015-09-30 19:53:24 【问题描述】:

Angular.js ngModel 能够声明parsers 和formatters 的链。更多细节可以在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】:

目前没有直接调用内部格式化链的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

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

【讨论】:

这太棒了!

以上是关于如何使用 ngModel 在 angularjs 指令中手动重新运行格式化程序链?的主要内容,如果未能解决你的问题,请参考以下文章

AngularJS ngModel 在 ui-bootstrap 选项卡集中不起作用

ngmodel 更改时未触发角度日期过滤器

ckeditor+angularjs directive

ngModel 格式化程序和解析器

ngModel

在Angularjs中格式化输入值