Compilation de chaînes HTML dynamics à partir d’une firebase database

La situation

Dans notre application Angular, une directive appelée Page, soutenue par un contrôleur, contient une div avec un atsortingbut ng-bind-html-unsafe. Ceci est assigné à une variable $ scope appelée ‘pageContent’. Cette variable se voit atsortingbuer du code HTML généré dynamicment à partir d’une firebase database. Lorsque l’utilisateur retourne à la page suivante, un appel à la firebase database est effectué et la variable pageContent est définie sur ce nouveau code HTML, qui est rendu à l’écran via ng-bind-html-unsafe. Voici le code:

Directive page

angular.module('myApp.directives') .directive('myPage', function ($comstack) { return { templateUrl: 'page.html', ressortingct: 'E', comstack: function comstack(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 } } } }; }); 

Modèle de directive de la page (“page.html” de la propriété templateUrl ci-dessus)

 
...
...

Contrôleur de page

 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; }); }); 

Ça marche. Nous voyons le HTML de la page de la firebase database bien rendu dans le navigateur. Lorsque l’utilisateur retourne à la page suivante, nous voyons le contenu de la page suivante, et ainsi de suite. Jusqu’ici tout va bien.

Le problème

Le problème ici est que nous voulons avoir du contenu interactif à l’intérieur du contenu d’une page. Par exemple, le code HTML peut contenir une image miniature où, lorsque l’utilisateur clique dessus, Angular doit faire quelque chose de génial, par exemple afficher une fenêtre modale contextuelle. J’ai placé des appels de méthode angular (ng-click) dans les chaînes HTML de notre firebase database, mais bien sûr, Angular ne reconnaîtra ni les appels de méthode ni les directives à moins de les parsingr et les comstackr.

Dans notre DB

Contenu pour la page 1:

 

Here's a cool pic of a lion. Click on him to see a large image.

Contenu pour la page 2:

 

Here's a snake. Click to make him hiss.

De retour dans le contrôleur de page, nous ajoutons la fonction $ scope correspondante:

Contrôleur de page

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

Je n’arrive pas à comprendre comment appeler cette méthode ‘doSomethingAwesome’ depuis la chaîne HTML de la firebase database. Je réalise qu’Angular doit parsingr la chaîne HTML d’une manière ou d’une autre, mais comment? J’ai lu des rumeurs vagues sur le service $ comstack, et copié et collé des exemples, mais rien ne fonctionne. En outre, la plupart des exemples montrent que le contenu dynamic n’est défini que pendant la phase de liaison de la directive. Nous voudrions que Page rest en vie tout au long de la vie de l’application. Il reçoit, comstack et affiche constamment du nouveau contenu au fur et à mesure que l’utilisateur fait défiler les pages.

Dans un sens abstrait, je suppose que vous pourriez dire que nous essayons d’implanter dynamicment des morceaux d’Angular dans une application angular, et que nous devons pouvoir les échanger.

J’ai lu plusieurs fois des documents Angular, ainsi que toutes sortes d’articles de blog, et JS Fiddled avec le code des personnes. Je ne sais pas si je comprends mal Angular ou si je manque quelque chose de simple, ou peut-être que je suis lent. En tout cas, je pourrais utiliser des conseils.

ng-bind-html-unsafe ne rend que le contenu en HTML. Il ne lie pas la scope angular au DOM résultant. Vous devez utiliser le service $comstack à cette fin. J’ai créé ce plunker pour montrer comment utiliser $comstack pour créer une directive rendant le code HTML dynamic saisi par les utilisateurs et lié à la scope du contrôleur. La source est publiée ci-dessous.

demo.html

 < !DOCTYPE html>       

Comstack dynamic HTML

script.js

 var app = angular.module('app', []); app.directive('dynamic', function ($comstack) { return { ressortingct: 'A', replace: true, link: function (scope, ele, attrs) { scope.$watch(attrs.dynamic, function(html) { ele.html(html); $comstack(ele.contents())(scope); }); } }; }); function MyController($scope) { $scope.click = function(arg) { alert('Clicked ' + arg); } $scope.html = 'Click me'; } 

Dans angular 1.2.10 la ligne scope.$watch(attrs.dynamic, function(html) { une erreur de caractère non valide car elle essayait de voir la valeur de attrs.dynamic qui était du texte HTML.

J’ai corrigé cela en récupérant l’atsortingbut depuis la propriété scope

  scope: { dynamic: '=dynamic'}, 

Mon exemple

 angular.module('app') .directive('dynamic', function ($comstack) { return { ressortingct: 'A', replace: true, scope: { dynamic: '=dynamic'}, link: function postLink(scope, element, attrs) { scope.$watch( 'dynamic' , function(html){ element.html(html); $comstack(element.contents())(scope); }); } }; }); 

Trouvé dans un groupe de discussion Google. Travaille pour moi.

 var $injector = angular.injector(['ng', 'myApp']); $injector.invoke(function($rootScope, $comstack) { $comstack(element)($rootScope); }); 

Vous pouvez utiliser

ng-bind-html https://docs.angularjs.org/api/ng/service/ $ sce

directive pour lier dynamicment HTML. Cependant, vous devez obtenir les données via le service $ sce.

S’il vous plaît voir la démo en direct à http://plnkr.co/edit/k4s3Bx

 var app = angular.module('plunker', []); app.controller('MainCtrl', function($scope,$sce) { $scope.getHtml=function(){ return $sce.trustAsHtml("Hi Rupesh hi dfdfdfdf!sdafsdfsdf"); } });    

Essayez ce code ci-dessous pour lier html via attr

 .directive('dynamic', function ($comstack) { return { ressortingct: 'A', replace: true, scope: { dynamic: '=dynamic'}, link: function postLink(scope, element, attrs) { scope.$watch( 'attrs.dynamic' , function(html){ element.html(scope.dynamic); $comstack(element.contents())(scope); }); } }; }); 

Essayez cet element.html (scope.dynamic); que element.html (attr.dynamic);