2014-10-08 3 views
1

Мне интересно, почему мои $ parsers вызывается, но мои $ formatters не вызываются. Я изменил plunker в Custom Control Example, чтобы включить $ parsers и $ formatters. Похоже, что мои $ parsers вызывается, но мои $ formatters не вызываются. Я использую $ parsers и/или $ formatters неправильно? Вот мой модифицированный плункер: http://plnkr.co/edit/o1EM05AtDGw2OMDwv9dR.

angular.module('customControl', ['ngSanitize']). 
    directive('contenteditable', ['$sce', function($sce) { 
    return { 
     restrict: 'A', // only activate on element attribute 
     require: '?ngModel', // get a hold of NgModelController 
     link: function(scope, element, attrs, ngModel) { 
     if (!ngModel) return; // do nothing if no ng-model 

     // Specify how UI should be updated 
     ngModel.$render = function() { 
      element.html($sce.getTrustedHtml(ngModel.$viewValue || '')); 
     }; 

     ngModel.$parsers.push(function (viewValue) { 
      console.log("parsing"); 
      return viewValue + "_extra_model_stuff"; 
     }); 

     ngModel.$formatters.push(function (modelValue) { 
      console.log("never formats : ("); 
      return modelValue + "_formatted_view_stuff"; 
     }); 

     // Listen for change events to enable binding 
     element.on('blur keyup change', function() { 
      scope.$apply(read); 
     }); 
     read(); // initialize 

     // Write data to the model 
     function read() { 
      var html = element.html(); 
      // When we clear the content editable the browser leaves a <br> behind 
      // If strip-br attribute is provided then we strip this out 
      if (attrs.stripBr && html == '<br>') { 
      html = ''; 
      } 
      ngModel.$setViewValue(html); 
     } 
     } 
    }; 
    }]); 

После более внимательном angular.js, похоже Ctrl относится к ngModelController. Я ожидал, что он будет ссылаться на ngModelController, к которому я добавлял formatters. Однако ctrl. $ Formatters - пустой массив, поэтому это должен быть другой ngModelController. Я не понимаю, почему.

$scope.$watch(function ngModelWatch() { 
    var modelValue = ngModelGet(); 

    // if scope model value and ngModel value are out of sync 
    // TODO(perf): why not move this to the action fn? 
    if (modelValue !== ctrl.$modelValue) { 
    ctrl.$modelValue = modelValue; 

    var formatters = ctrl.$formatters, 
     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(undefined, modelValue, viewValue, noop); 
    } 
    } 

    return modelValue; 
}); 
+0

Форматор ** ** вызывается в вашем Plunker. – zeroflagL

+0

@zeroflagL Вы видите 'никогда не форматирует: (« «регистрируетесь?» Я не использую Chrome 37.0.2062.124. –

+0

Да, когда я изменяю текст в текстовом поле. – zeroflagL

ответ

2

Как было отмечено выше:

форматера вызывается, когда изменения модели и должен быть оказаны. Парсер вызывается, когда представление пользовательского интерфейса изменяется, и модель должна обновляться. Когда вы редактируете контент, который вы редактируете, вы меняете представление пользовательского интерфейса, поэтому вызывается парсер и обновляется модель. Когда вы редактируете текстовое поле, то сначала происходит то же самое. Но contenteditable по-прежнему показывает старое значение модели. Таким образом, форматировщик должен быть вызван, чтобы показать новый.

Парсер вызывается, но его собственный, а не ваш.

Смежные вопросы