La situazione
Nella nostra app Angular è nidificata una direttiva chiamata Page, supportata da un controller, che contiene un div con un attributo ng-bind-html-unsafe. Questo è assegnato a una var $ scope chiamata 'pageContent'. A questa var viene assegnato HTML generato dinamicamente da un database. Quando l'utente passa alla pagina successiva, viene effettuata una chiamata al DB e pageContent var viene impostato su questo nuovo HTML, che viene reso sullo schermo tramite ng-bind-html-unsafe. Ecco il codice:
Direttiva sulla pagina
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
}
}
}
};
});
Modello della direttiva di pagina ("page.html" dalla proprietà templateUrl sopra)
<div ng-controller="PageCtrl" >
...
<!-- dynamic page content written into the div below -->
<div ng-bind-html-unsafe="pageContent" >
...
</div>
Controller di pagina
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;
});
});
Che funzioni. Vediamo l'HTML della pagina dal DB reso bene nel browser. Quando l'utente passa alla pagina successiva, vediamo il contenuto della pagina successiva e così via. Fin qui tutto bene.
Il problema
Il problema qui è che vogliamo avere contenuti interattivi all'interno del contenuto di una pagina. Ad esempio, l'HTML può contenere un'immagine in miniatura in cui, quando l'utente fa clic su di essa, Angular dovrebbe fare qualcosa di fantastico, come la visualizzazione di una finestra modale pop-up. Ho inserito chiamate di metodo Angular (ng-click) nelle stringhe HTML nel nostro database, ma ovviamente Angular non riconoscerà né chiamate di metodo né direttive a meno che non analizzi in qualche modo la stringa HTML, le riconosca e le compili.
Nel nostro DB
Contenuto per la pagina 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>
Contenuto per Pagina 2:
<p>Here's a snake. <img src="snake.png" ng-click="doSomethingAwesone('snake', 'playSound')" >Click to make him hiss.</p>
Di nuovo nel controller Pagina, aggiungiamo la funzione $ scope corrispondente:
Controller di pagina
$scope.doSomethingAwesome = function( id, action ) {
console.log( "Going to do " + action + " with "+ id );
}
Non riesco a capire come chiamare quel metodo 'doSomethingAwesome' dall'interno della stringa HTML dal DB. Mi rendo conto che Angular deve analizzare la stringa HTML in qualche modo, ma come? Ho letto vaghi borbottii sul servizio $ compilare, copiato e incollato alcuni esempi, ma nulla funziona. Inoltre, la maggior parte degli esempi mostra che il contenuto dinamico viene impostato solo durante la fase di collegamento della direttiva. Vorremmo che Page rimanesse vivo per tutta la vita dell'app. Riceve, compila e visualizza costantemente nuovi contenuti mentre l'utente scorre le pagine.
In senso astratto, suppongo che potresti dire che stiamo cercando di nidificare in modo dinamico blocchi di angolari all'interno di un'app angolare e che dobbiamo essere in grado di scambiarli dentro e fuori.
Ho letto varie parti della documentazione angolare più volte, così come tutti i tipi di post sul blog, e JS ha manipolato il codice delle persone. Non so se sto completamente fraintendendo Angular, o semplicemente mancando qualcosa di semplice, o forse sono lento. In ogni caso, potrei usare qualche consiglio.