Как скомпилировать html за пределами области действия ng-app после частичного обновления

#javascript #asp.net #angularjs

#javascript #asp.net #angularjs

Вопрос:

У меня есть пользовательский элемент управления, который использует anguar.js и объявляет a div с ng-app где-то внутри. Другая часть системы не использует angular.js его и даже не ссылается на него.

Теперь проблема в том, что после частичного обновления html (например, с помощью update-panel) Мне нужно перекомпилировать его (потому что он введен в DOM), и я технически не могу этого сделать, поскольку заменяется весь html вместе с ng-app объявлением.

И у меня нет доступа к $compile сервису (хорошо, я могу получить его с помощью $injector , но где мне его получить $scope ?)

 function AfterPartialUpdate(containerElement) {
    var injector = angular.injector(['ng']);
    injector.invoke(function($compile) {
        $compile(containerElement)( ???need scope, which is lost );
    });
};
 

Я могу сохранить область видимости в момент начальной загрузки страницы в некоторой глобальной переменной.
Но перекомпиляция с использованием той же области приводит к постепенному увеличению $$watchers коллекции и другим нежелательным побочным эффектам…

Я предполагаю, что должен быть способ заставить angular выполнять все тот же javascript, который он выполняет во время начальной загрузки страницы, т. Е. Создавать модули, просматривать html, создавать экземпляры контроллеров и т. Д.?

Комментарии:

1. инжектор также предоставляет вам сервис $rootScope. Попробуйте этот инжектор.invoke(функция($compile, $rootScope) { $compile(containerElement)($rootScope); });

2. но я предполагаю, что $rootScope — это не то, что мне на самом деле нужно? потому что мне нужна дочерняя область моего контроллера

3. Вы сказали, что заменяете все ng-app?

4. ДА. Я пытался использовать $compile(containerElement)($rootScope) , и это делается без ошибок, но когда я это делаю containerElement.scope() , я получаю undefined , и результирующий html неверен (например, у меня <div ng-if='dataSource != null' , очевидно dataSource , равно null, поэтому содержимое пустое)

5. Можете ли вы опубликовать свой html и другой соответствующий код angularjs?

Ответ №1:

Инжектор предоставляет вам сервис $rootScope. Попробуйте использовать его для компиляции элемента:

 var injector = angular.injector(['ng']);
injector.invoke(function($compile, $rootScope) {
    $compile(containerElement)($rootScope);
});
 

Комментарии:

1. Я нашел еще одну интересную вещь — для того, чтобы привязки применялись после компиляции шаблона, вам нужно вызвать $rootScope. $apply(); . Если вы этого не сделаете, привязки не будут разрешены до каких-либо изменений (например, пользовательского ввода). Проверьте эту скрипку jsfiddle.net/fpns8/4

2. это правда, вы всегда должны вызывать $apply после ручной компиляции, чтобы разрешить текущую привязку данных.