A situação
Aninhada em nosso aplicativo Angular está uma diretiva chamada Page, apoiada por um controlador, que contém uma div com um atributo ng-bind-html-unsafe. Isso é atribuído a uma variável $ scope chamada 'pageContent'. Essa var recebe o HTML gerado dinamicamente a partir de um banco de dados. Quando o usuário muda para a página seguinte, é feita uma chamada ao banco de dados e a pageContent var é definida para esse novo HTML, que é renderizado na tela por meio de ng-bind-html-unsafe. Aqui está o código:
Diretiva de página
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
}
}
}
};
});
Modelo da diretiva de página ("page.html" da propriedade templateUrl acima)
<div ng-controller="PageCtrl" >
...
<!-- dynamic page content written into the div below -->
<div ng-bind-html-unsafe="pageContent" >
...
</div>
Controlador de página
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;
});
});
Isso funciona. Vemos o HTML da página do banco de dados renderizado de maneira agradável no navegador. Quando o usuário passa para a próxima página, vemos o conteúdo da próxima página e assim por diante. Por enquanto, tudo bem.
O problema
O problema aqui é que queremos ter conteúdo interativo dentro do conteúdo de uma página. Por exemplo, o HTML pode conter uma imagem em miniatura na qual, quando o usuário clica nela, o Angular deve fazer algo impressionante, como exibir uma janela modal pop-up. Coloquei chamadas de método Angular (ng-click) nas seqüências HTML em nosso banco de dados, mas é claro que o Angular não reconhecerá chamadas ou diretivas de método, a menos que de alguma forma analise a sequência HTML, as reconheça e as compile.
No nosso banco de dados
Conteúdo da página 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>
Conteúdo da página 2:
<p>Here's a snake. <img src="snake.png" ng-click="doSomethingAwesone('snake', 'playSound')" >Click to make him hiss.</p>
De volta ao controlador de página, adicionamos a função $ scope correspondente:
Controlador de página
$scope.doSomethingAwesome = function( id, action ) {
console.log( "Going to do " + action + " with "+ id );
}
Não consigo descobrir como chamar esse método 'doSomethingAwesome' de dentro da string HTML do banco de dados. Sei que Angular precisa analisar a string HTML de alguma forma, mas como? Eu li vagos murmúrios sobre o serviço de compilação $, copiei e colei alguns exemplos, mas nada funciona. Além disso, a maioria dos exemplos mostra o conteúdo dinâmico sendo definido apenas durante a fase de vinculação da diretiva. Queremos que Page permaneça vivo durante toda a vida do aplicativo. Ele constantemente recebe, compila e exibe novo conteúdo à medida que o usuário percorre as páginas.
Em um sentido abstrato, acho que você poderia dizer que estamos tentando aninhar dinamicamente pedaços de Angular em um aplicativo Angular e precisamos ser capazes de trocá-los.
Li várias partes da documentação do Angular várias vezes, além de todos os tipos de postagens no blog, e o JS brincou com o código das pessoas. Não sei se estou entendendo completamente o Angular, ou apenas perdendo algo simples, ou talvez seja lento. De qualquer forma, eu poderia usar alguns conselhos.