Как вручную перезапустить цепочку форматирования в директиве angularjs с помощью ngModel?

Angular.js ngModel имеет возможность объявить цепочку парсеров и форматеров. Некоторые подробности можно найти в великолепном ответе на вопрос "Как выполнить двустороннюю фильтрацию в angular.js?"

Теперь цепочка форматирования будет выполняться только в случае обновления ngModel. поэтому, если у вас есть второй входной параметр, который влияет на viewValue (используется в одном из средств форматирования), это не приведет к обновлению View. похоже, насколько я обнаружил, ngModel использует только простые $watch - поэтому, если ваша модель является коллекцией / объектом, она не сработает, если подэлементы будут изменены.

Каков наилучший способ реализовать глубокие часы для ngModel -
или следите за дополнительным параметром, который должен перезапустить цепочку форматирования?

Есть и другие подобные вопросы:
Angularjs: как "перезапустить" $ форматтеры, когда некоторые настройки изменены?

1 ответ

В настоящее время нет прямого API для вызова внутренней цепочки форматирования. для этого есть запрос на функцию github. В качестве обходного пути вы можете просто скопировать внутренний код:

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);
    }

}

этот Plunker демонстрирует использование в сочетании с часами для дополнительных параметров:

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

это второй плункер, демонстрирующий глубинные часы на ngModel

// deepwatch ngModel
scope.$watch(
    function(){
        return ngModelCtrl.$modelValue;
    },
    function(newData) {
        runFormatters(ngModelCtrl);
    },
    true
);
Другие вопросы по тегам