状況
私たちのAngularアプリ内にネストされているのは、ng-bind-html-unsafe属性を持つdivを含む、コントローラーによってサポートされるPageというディレクティブです。これは、「pageContent」という$ scope変数に割り当てられます。この変数には、データベースから動的に生成されたHTMLが割り当てられます。ユーザーが次のページに移動すると、DBが呼び出され、pageContent変数がこの新しいHTMLに設定され、ng-bind-html-unsafeを介して画面上にレンダリングされます。これがコードです:
ページディレクティブ
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
}
}
}
};
});
ページディレクティブのテンプレート(上記のtemplateUrlプロパティの "page.html")
<div ng-controller="PageCtrl" >
...
<!-- dynamic page content written into the div below -->
<div ng-bind-html-unsafe="pageContent" >
...
</div>
ページコントローラー
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;
});
});
うまくいきます。ブラウザーで適切にレンダリングされたDBからのページのHTMLが表示されます。ユーザーが次のページに移動すると、次のページのコンテンツが表示されます。ここまでは順調ですね。
問題
ここでの問題は、ページのコンテンツ内にインタラクティブなコンテンツを含めることです。たとえば、HTMLにはサムネイル画像が含まれている可能性があり、ユーザーがクリックすると、Angularはポップアップモーダルウィンドウの表示など、すばらしい機能を実行します。私はデータベースのHTML文字列にAngularメソッド呼び出し(ng-click)を配置しましたが、もちろん、Angularは、何らかの方法でHTML文字列を解析して認識し、コンパイルしない限り、メソッド呼び出しまたはディレクティブを認識しません。
私たちのDBで
ページ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>
ページ2のコンテンツ:
<p>Here's a snake. <img src="snake.png" ng-click="doSomethingAwesone('snake', 'playSound')" >Click to make him hiss.</p>
ページコントローラに戻り、対応する$ scope関数を追加します。
ページコントローラー
$scope.doSomethingAwesome = function( id, action ) {
console.log( "Going to do " + action + " with "+ id );
}
DBのHTML文字列内から「doSomethingAwesome」メソッドを呼び出す方法がわかりません。AngularはHTML文字列をどうにかして解析しなければならないことを理解していますが、どうやって?$ compileサービスに関する漠然とした不平を読み、いくつかの例をコピーして貼り付けましたが、何も機能しません。また、ほとんどの例では、ディレクティブのリンク段階でのみ動的コンテンツが設定されることを示しています。アプリの存続期間中、Pageを存続させたいと思います。ユーザーがページをめくると、常に新しいコンテンツを受け取り、コンパイルして表示します。
抽象的な意味では、Angularアプリ内でAngularのチャンクを動的にネストしようとしているので、それらを入れ替えできるようにする必要があると言えます。
Angularのさまざまなドキュメントや、あらゆる種類のブログ投稿、JSのコードを何度も読んだことがあります。Angularを完全に誤解しているのか、単純なものを見逃しているのか、遅いのかわかりません。いずれにせよ、私はいくつかのアドバイスを使用することができます。