Обновить модель из директивы из цикла $apply или $digest в AngularJS

Я пытаюсь обновить модель из директивы, и у меня возникают проблемы, когда $apply или $digest уже выполняются. И у меня есть несколько вопросов:

  1. Почему scope[attrs.ngModel] существует, а ngModel.$modelValue не существует на этапе $apply?
  2. Почему представление не всегда может быть обновлено в фазе $digest (особенно в сложных ситуациях)?
  3. Является ли фаза $digest локальной $digest() или $root.$digest() (из $apply()) в моем примере?
require: '?ngModel',
link: function(scope, element, attrs, ngModel) {

  element.bind('myEvent', function(e) {        
    //Update model from directive in phase:               $apply  |  $digest

    scope[attrs.ngModel].value = scope.$$phase; //Model: '$apply' | '$digest'
    //or
    ngModel.$modelValue.value  = scope.$$phase; //Model: 'none'   | '$digest'
    //or
    ngModel.$modelValue.value  = scope.$$phase; //Model: ''       | '$digest'
    ngModel.$setViewValue(ngModel.$modelValue);
  });
}

Демонстрация в реальном времени: http://plnkr.co/edit/gVY6GJejEKCLdTIXNAzK?p=preview


person tamtakoe    schedule 03.08.2013    source источник


Ответы (1)


  1. Это потому, что angular не знает, как сопоставить модель с вашим элементом DIV. angular имеет встроенные реализации модели практически для любого элемента INPUT (кроме файла типа INPUT), SELECT и TEXTAREA. В вашем случае (DIV с примененной ng-моделью) нет подходящего адаптера модели, известного угловому. какое свойство/атрибут элемента DIV должно быть угловым, чтобы синхронизироваться с вашей моделью?? вот почему у вас нет $modelValue. что вам нужно сделать, это предоставить адаптер пользовательской модели для angular ИЛИ вам нужно использовать элемент INPUT, SELECT или TEXTAREA.

  2. потому что в фазе $digest angular предполагает, что все изменения сделаны.

  3. нет локальной или глобальной фазы $digest. фазы всегда связаны с вашим ng-app.

person lgersman    schedule 16.08.2013
comment
Как я могу создать и предоставить адаптер пользовательской модели? Или посоветуйте пожалуйста подходящую статью. Как я могу изменить модель на этапе $digest, если angular предполагает, что все изменения сделаны? Теперь я использую scope.$$phase || scope.$apply, но это плохой способ, я думаю... - person tamtakoe; 17.08.2013
comment
Я действительно уверен, что ваш пример кода и вопрос не отражают вашу реальную проблему. то, что вы делаете в своем коде... почти неправильно, в любом случае, что вы хотите сделать, и мне очень жаль это говорить, на самом деле :-) если вы хотите сохранить свой код, единственный выбор, который у вас есть, - это проверить текущую фазу и в случае, если это НЕ $apply : оберните ваш установщик значений внутри области видимости. Но, как я уже сказал, вы должны переосмыслить код примера, чтобы показать, что вы ДЕЙСТВИТЕЛЬНО хотите. - person lgersman; 20.08.2013