2016-03-10 2 views
0

Мы следующий сценарий:контроллера ngModel и templateUrls в AngularJS 1.5

есть контейнер, который может иметь х входные элементы (х> = 0) Каждые входной элемент использует нормальные нг-связывают

В в контейнере есть функция, которая добавляет $ parsers и $ validators к каждому включенному ngModelController.

код выглядит следующим образом:

<form-element> 
    <fs-input-a ng-required="true" ng-model="model.streetname" name="streetname"></fs-input-a> 
    <fs-input-b ng-required="true" ng-maxlength="5" ng-pattern="/\d$/" ng-model="model.streetnr" name="streetnr"></fs-input-b> 
</form-element> 

В способе связи в "элемент формы" директивы мы называем что-то вроде этого: управления вар = элемент [0] .querySelectorAll ('[ng- model] '), i, ngModel;

// Get all ngModel controllers 
if (controls.length) { 
for (i = 0; i < controls.length; i++) { 
    ngModel = angular.element(controls[i]).controller('ngModel'); 
    ngModel.$parsers.push(function(value) { 
     ... 
    }.bind(ngModel)); 
    ngModel.$validators.removeHidden = function() { 
     // on validation remove the hideError flag 
     this.$hideError = undefined; 
     return true; 
    }.bind(ngModel); 
    } 
} 

Это работало отлично под AngularJS 1.4.x

В AngularJS 1.5.x работает только если шаблон во входных директив она непосредственно определяется с помощью шаблона: «...» Если мы используем templateUrl : «...» у нас есть проблема, что ngModel будет неопределенным. В элементах управления [i] Я получаю правый элемент, и есть атрибут ng-model, но, похоже, что AngularJS 1.5 не скомпилировал элемент.

Есть ли лучший способ манипулировать ngModels дочерних элементов?

+0

Попробуйте ввести логику в крючок жизненного цикла $ onInit. – Prashant

+0

Я пробовал. Та же проблема. –

ответ

0

Компиляция является ленивой, поэтому не будет способа сделать это надежно, как вы ее получили в настоящее время, родительская директива не имеет способа узнать, что ее дети скомпилированы и готовы. $onInit вызываются, когда контроллеры родителя/одноуровневые разрешаются, и от Angular 1.5.3 docs, $postLink которая (скорее всего?) Последнего метода Жизненного цикла вызывается при составлении директивы:

$ postLink() - Вызывается после того, как элемент этого контроллера и его дети связаны. Подобно функции post-link, этот крючок можно использовать для настройки обработчиков событий DOM и прямого манипулирования DOM. Обратите внимание, что дочерние элементы, содержащие директивы templateUrl, не будут скомпилированы и связаны, так как они ожидают, что их шаблон будет загружаться асинхронно, а их собственная компиляция и привязка будут приостановлены до тех пор, пока это не произойдет.

Это, кажется, говорит, что вы не должны пытаться получить доступ к контроллерам детей через DOM независимо от того, что.

Есть ли какая-либо конкретная причина, по которой вам необходимо прокручивать все контроллеры одновременно? Если вы просто выполняете такую ​​же инициализацию для всех контроллеров, альтернативой будет добавление контейнеров в качестве требуемого контроллера в дочерних элементах и ​​их выполнение, например. в дочерних компонентах:

require: { 
    ... 
    parent: '^parentComponent' 
}, 
controller: function() { 
    this.$onInit =() => this.parent.initialiseNgModel(...); 
} 

В качестве альтернативы, использование нг-инициализация или директиву атрибута, если дети не могут быть изменены (или просто держать код отдельным).

Если абсолютно необходимо, чтобы родительский контроллер выполнял все сразу. Тогда не очень приятным решением было бы добавить способ для компонентов для детей сигнализировать, что они были скомпилированы, а родитель подсчитывает, сколько их есть и ждет, когда все они будут закончены, прежде чем продолжить свой код.

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