AngularJS, как принудительно перерисовывать ввод -при размытии

У меня есть пользовательский код проверки, который включает форматирование $. (Я сохраняю валюту в пенсах для корректности, но отображаю в фунтах.)

Если пользователь вводит «10» в поле ввода (, которое является допустимым значением ), ввод продолжает отображать «10» после перехода к следующему полю.

Я хотел бы, чтобы он отображал 10,00 для согласованности.

Если бы модель изменила значение на 1000, средство форматирования заставило бы поле отображать «10,00».

Я бы хотел, чтобы форматер работал на field.blur()(до тех пор, пока ввод действителен ).

Моя проблема заключается в том, что если я изменю значение модели с 10 на 10, понятно, что изменений не будет, и поэтому поле не будет повторно -визуализироваться.

код:

var CURRENCY_REGEXP = /^\-?\d+(\.?\d?\d?)?$/;
app.directive('currency', function() {
  return {
    require: 'ngModel',
    link: function(scope, elm, attrs, ctrl) {
      ctrl.$parsers.unshift(function(viewValue) {
        if (CURRENCY_REGEXP.test(viewValue)) {
          // it is valid
          ctrl.$setValidity('currency', true);
          console.log("valid");
          return viewValue * 100;
        } else if (viewValue === '') {
          return 0;
        } else {
          // it is invalid, return undefined (no model update)
          ctrl.$setValidity('currency', false);
          console.log("invalid");
          return undefined;
        }
      });
      ctrl.$formatters.push(function(modelValue) {
         if (modelValue === 0) { // we're using integer pence, so this is safe
             return '';
         }
         return (modelValue / 100).toFixed(2); 
      });
    }
  };
});

P.S. Это не имеет ничего общего со встроенным -Angular в «валюте».


Обновление :Я добавил директиву «renderOnBlur», согласно ответу Энди. Он вызывается, но вызов метода рендеринга не приводит -к рендерингу ввода. т. е. «10» остается как «10», а не меняется на «10,00» по желанию.

(Когда значение модели изменяется в этих полях, они правильно отображаются с двумя десятичными знаками.)

Страница, которую упоминает Эндиhttp://docs.angularjs.org/api/ng.directive:ngModel.NgModelControllerговорит, что вы должны реализовать $renderсамостоятельно. Это кажется странным, так как входные данные уже отображаются правильно, когда значение модели изменяется.

app.directive('renderOnBlur', function() {
    return {
        require: 'ngModel',
        restrict: 'A',
        link: function(scope, elm, attrs, ctrl) {
            elm.bind('blur', function() {
                console.log('rendering ctrl', ctrl);
                ctrl.$render();
            });
        }
    };  
});

P.S. Я понятия не имею, что restrict: 'A',делает -это настоящий груз -культовое программирование в худшем его проявлении. require: 'ngModel',кажется необходимым для заполнения параметра ctrl.


Вдохновленный ответом @Dan Doyen, я переписал его как:

app.directive('renderOnBlur', function() {
    return {
        require: 'ngModel',
        restrict: 'A',
        link: function(scope, elm, attrs, ctrl) {
            elm.bind('blur', function() {
                var viewValue = ctrl.$modelValue;
                for (var i in ctrl.$formatters) {
                    viewValue = ctrl.$formatters[i](viewValue);
                }
                ctrl.$viewValue = viewValue;
                ctrl.$render();
            });
        }
    };  
});

Преимущество этого заключается в том, что он является универсальным для любого $formatter, а не повторяет код форматирования, как в ответе Дэна.

23
задан fadedbee 13 July 2012 в 15:19
поделиться