Sytuacja
W naszej aplikacji Angulara jest zagnieżdżona dyrektywa o nazwie Page, wspierana przez kontroler, która zawiera element div z atrybutem ng-bind-html-unsafe. Jest to przypisane do zmiennej $ scope o nazwie „pageContent”. Ta zmienna otrzymuje dynamicznie generowany kod HTML z bazy danych. Kiedy użytkownik przechodzi do następnej strony, następuje wywołanie bazy danych, a zmienna pageContent jest ustawiana na ten nowy kod HTML, który jest renderowany na ekranie przez ng-bind-html-unsafe. Oto kod:
Dyrektywa strony
angular.module('myApp.directives')
.directive('myPage', function ($compile) {
return {
templateUrl: 'page.html',
restrict: 'E',
compile: function compile(element, attrs, transclude) {
// does nothing currently
return {
pre: function preLink(scope, element, attrs, controller) {
// does nothing currently
},
post: function postLink(scope, element, attrs, controller) {
// does nothing currently
}
}
}
};
});
Szablon dyrektywy strony („page.html” z właściwości templateUrl powyżej)
<div ng-controller="PageCtrl" >
...
<!-- dynamic page content written into the div below -->
<div ng-bind-html-unsafe="pageContent" >
...
</div>
Kontroler strony
angular.module('myApp')
.controller('PageCtrl', function ($scope) {
$scope.pageContent = '';
$scope.$on( "receivedPageContent", function(event, args) {
console.log( 'new page content received after DB call' );
$scope.pageContent = args.htmlStrFromDB;
});
});
To działa. Widzimy, że kod HTML strony z bazy danych jest ładnie renderowany w przeglądarce. Kiedy użytkownik przechodzi do następnej strony, widzimy zawartość następnej strony i tak dalej. Na razie w porządku.
Problem
Problem polega na tym, że chcemy mieć interaktywną zawartość w treści strony. Na przykład kod HTML może zawierać miniaturę, w której po kliknięciu przez użytkownika Angular powinien zrobić coś niesamowitego, na przykład wyświetlić wyskakujące okienko modalne. Umieściłem wywołania metod Angular (ng-click) w łańcuchach HTML w naszej bazie danych, ale oczywiście Angular nie rozpozna ani wywołań metod, ani dyrektyw, chyba że w jakiś sposób przeanalizuje ciąg HTML, rozpozna je i skompiluje.
W naszej DB
Treść strony 1:
<p>Here's a cool pic of a lion. <img src="lion.png" ng-click="doSomethingAwesone('lion', 'showImage')" > Click on him to see a large image.</p>
Treść strony 2:
<p>Here's a snake. <img src="snake.png" ng-click="doSomethingAwesone('snake', 'playSound')" >Click to make him hiss.</p>
W kontrolerze Page, dodajemy następnie odpowiednią funkcję $ scope:
Kontroler strony
$scope.doSomethingAwesome = function( id, action ) {
console.log( "Going to do " + action + " with "+ id );
}
Nie mogę dowiedzieć się, jak wywołać tę metodę „doSomethingAwesome” z ciągu znaków HTML z bazy danych. Zdaję sobie sprawę, że Angular musi jakoś przeanalizować ciąg HTML, ale jak? Przeczytałem niejasne mamrotania o usłudze $ compile, skopiowałem i wkleiłem kilka przykładów, ale nic nie działa. Ponadto większość przykładów pokazuje, że zawartość dynamiczna jest ustawiana tylko w fazie linkowania dyrektywy. Chcielibyśmy, aby Page działała przez cały okres użytkowania aplikacji. Stale otrzymuje, kompiluje i wyświetla nowe treści, gdy użytkownik przegląda strony.
W sensie abstrakcyjnym myślę, że można powiedzieć, że próbujemy dynamicznie zagnieżdżać fragmenty Angular w aplikacji Angular i musimy mieć możliwość ich wymiany.
Wielokrotnie czytałem różne fragmenty dokumentacji Angular, a także wszelkiego rodzaju posty na blogu i JS Fiddled z kodem ludzi. Nie wiem, czy kompletnie nie rozumiem Angulara, czy po prostu przeoczę coś prostego, czy może jestem wolny. W każdym razie przydałaby mi się rada.