Kompilowanie dynamicznych ciągów HTML z bazy danych

Sytuacja

Zagnieżdżona w naszej aplikacji Angular jest dyrektywa o nazwie Strona, wspierana przez kontroler, który zawiera div z atrybutem ng-bind-html-unsafe. Jest to przypisane do zmiennej $ scope o nazwie „pageContent”. Ta zmienna otrzymuje przypisany dynamicznie generowany kod HTML z bazy danych. Gdy użytkownik przejdzie do następnej strony, wywoływany jest DB, a var pageContent jest ustawiony na ten nowy 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 powyższej właściwości templateUrl)

<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 HTML strony z DB renderowanego ładnie w przeglądarce. Gdy użytkownik przejdzie do następnej strony, zobaczymy zawartość następnej strony i tak dalej. Jak na razie dobrze.

Problem

Problem polega na tym, że chcemy mieć interaktywną zawartość wewnątrz treści strony. Na przykład HTML może zawierać obraz miniatury, w którym, gdy użytkownik go kliknie, Angular powinien zrobić coś niesamowitego, na przykład wyświetlić wyskakujące okno modalne. Umieściłem wywołania metody Angulara (ng-click) w łańcuchach HTML w naszej bazie danych, ale oczywiście Angular nie rozpozna wywołań metod ani dyrektyw, chyba że w jakiś sposób przeanalizuje ciąg HTML, rozpozna je i skompiluje.

W naszym DB

Zawartość 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ść dla strony 2:

<p>Here's a snake. <img src="snake.png" ng-click="doSomethingAwesone('snake', 'playSound')" >Click to make him hiss.</p>

Po powrocie do kontrolera strony dodajemy odpowiednią funkcję $ scope:

Kontroler strony

$scope.doSomethingAwesome = function( id, action ) {
    console.log( "Going to do " + action + " with "+ id );
}

Nie wiem, jak wywołać tę metodę „doSomethingAwesome” z ciągu HTML z bazy danych. Zdaję sobie sprawę, że Angular musi jakoś przeanalizować łańcuch HTML, ale jak? Przeczytałem niejasne mamrotanie o usłudze $ compile i skopiowałem i wkleiłem kilka przykładów, ale nic nie działa. Ponadto większość przykładów pokazuje, że dynamiczna treść jest ustawiana tylko podczas fazy łączenia dyrektywy. Chcielibyśmy, aby strona pozostała przy życiu przez cały okres użytkowania aplikacji. Stale odbiera, kompiluje i wyświetla nową zawartość, gdy użytkownik przegląda strony.

W sensie abstrakcyjnym, myślę, że można powiedzieć, że próbujemy dynamicznie zagnieżdżać porcje Angular w aplikacji Angular i musimy być w stanie zamienić je i wyrzucić.

Wielokrotnie czytałem różne fragmenty dokumentacji Angulara, a także różnego rodzaju posty na blogach i JS Fiddled z kodem ludzi. Nie wiem, czy całkowicie źle rozumiem Angular, czy po prostu brakuje czegoś prostego, a może jestem powolny. W każdym razie mógłbym skorzystać z porady.

questionAnswers(5)

yourAnswerToTheQuestion