Die Situation
In unserer Angular-App ist eine Direktive namens Page verschachtelt, die von einem Controller unterstützt wird und ein div mit dem Attribut ng-bind-html-unsafe enthält. Dies wird einer $ scope-Variable namens 'pageContent' zugewiesen. Dieser Variable wird dynamisch generiertes HTML aus einer Datenbank zugewiesen. Wenn der Benutzer zur nächsten Seite blättert, wird ein Aufruf an die Datenbank vorgenommen, und die Variable pageContent wird auf diesen neuen HTML-Code gesetzt, der über ng-bind-html-unsafe auf dem Bildschirm gerendert wird. Hier ist der Code:
Seitenrichtlinie
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
}
}
}
};
});
Vorlage der Seitenanweisung ("page.html" aus der Eigenschaft templateUrl oben)
<div ng-controller="PageCtrl" >
...
<!-- dynamic page content written into the div below -->
<div ng-bind-html-unsafe="pageContent" >
...
</div>
Seitencontroller
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;
});
});
Das funktioniert. Wir sehen den HTML-Code der Seite aus der Datenbank im Browser gut gerendert. Wenn der Benutzer zur nächsten Seite wechselt, wird der Inhalt der nächsten Seite usw. angezeigt. So weit, ist es gut.
Das Problem
Das Problem hierbei ist, dass wir interaktiven Inhalt innerhalb des Inhalts einer Seite haben möchten. Beispielsweise kann der HTML-Code ein Miniaturbild enthalten, in dem Angular, wenn der Benutzer darauf klickt, etwas Fantastisches tun sollte, z. B. das Anzeigen eines modalen Popup-Fensters. Ich habe Angular-Methodenaufrufe (ng-click) in die HTML-Zeichenfolgen in unserer Datenbank eingefügt, aber Angular erkennt natürlich weder Methodenaufrufe noch Direktiven, es sei denn, es analysiert die HTML-Zeichenfolge, erkennt sie und kompiliert sie.
In unserer DB
Inhalt für Seite 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>
Inhalt für Seite 2:
<p>Here's a snake. <img src="snake.png" ng-click="doSomethingAwesone('snake', 'playSound')" >Click to make him hiss.</p>
Zurück im Page-Controller fügen wir dann die entsprechende $ scope-Funktion hinzu:
Seitencontroller
$scope.doSomethingAwesome = function( id, action ) {
console.log( "Going to do " + action + " with "+ id );
}
Ich kann nicht herausfinden, wie diese 'doSomethingAwesome'-Methode aus der HTML-Zeichenfolge der Datenbank heraus aufgerufen werden kann. Mir ist klar, dass Angular die HTML-Zeichenfolge irgendwie analysieren muss, aber wie? Ich habe vage Gemurmel über den $ compile-Dienst gelesen und einige Beispiele kopiert und eingefügt, aber nichts funktioniert. Außerdem zeigen die meisten Beispiele, dass dynamischer Inhalt nur während der Verknüpfungsphase der Direktive festgelegt wird. Wir möchten, dass Page während des gesamten Lebens der App am Leben bleibt. Es empfängt, kompiliert und zeigt ständig neue Inhalte an, während der Benutzer durch die Seiten blättert.
In einem abstrakten Sinne könnte man sagen, dass wir versuchen, Angular-Blöcke dynamisch in einer Angular-App zu verschachteln und sie ein- und austauschen müssen.
Ich habe verschiedene Teile der Angular-Dokumentation mehrmals gelesen sowie alle Arten von Blog-Posts und JS hat mit dem Code der Leute herumgespielt. Ich weiß nicht, ob ich Angular völlig falsch verstehe oder nur etwas Einfaches vermisse oder ob ich langsam bin. Auf jeden Fall könnte ich einen Rat gebrauchen.