Collega Angularjs all’elemento html appena creato dynamicmente

Ho una scheda con più tabs che una volta cliccato su chiama un servizio per restituire alcuni dati. Alcuni di questi dati restituiscono moduli html e sono molto casuali. Voglio raccogliere i valori inseriti e inviare i dati tramite un servizio al server. Il problema che ho è che non riesco a ottenere i dati dagli elementi di input nel html che sto creando dynamicmente.

Ho creato un Plunker per mostrare qual è il problema. Nota che il valore html può cambiare in qualsiasi momento in modo che l’html non funzioni correttamente. Qui il codice del plunker, ma per favore guarda il plunker per vedere meglio cosa sta succedendo.

app.js

var app = angular.module('plunker', []); app.controller('MainCtrl', function($scope, $sce, $compile) { $scope.name = 'World'; $scope.html = ""; $scope.htmlElement = function(){ var html = ""; return $sce.trustAsHtml(html); } }); 

index.html

     AngularJS Plunker document.write('');      

Hello {{name}}!

{{html}}

Una soluzione sarebbe usare ngInclude con $ templateCache, come dimostrato in questo Plunker .

Ci sono un paio di cose da notare.

Il primo è che puoi recuperare il tuo template usando un servizio e aggiungerlo a $ templateCache, come descritto qui (esempio copiato):

 myApp.service('myTemplateService', ['$http', '$templateCache', function ($http, $templateCache) { $http(/* ... */).then(function (result) { $templateCache.put('my-dynamic-template', result); }); }]); 

Quindi puoi includerlo nel tuo modello come segue:

 

ngInclude consentirà l’associazione dati sulla stringa html, quindi non è necessario ngBindHtml.

Il secondo è che, quando ngInclude crea un nuovo ambito, l’accesso alla proprietà html al di fuori dell’ambito appena creato non funzionerà correttamente a meno che non lo acceda tramite un object sull’ambito genitore (es. ng-model="data.html" invece di ng-model="html" . Si noti che $scope.data = {} nell’ambito genitore è ciò che rende l’html accessibile al di fuori dell’ambito ngInclude in questo caso.

(Vedi questa risposta per ulteriori informazioni sul motivo per cui dovresti sempre usare un punto nei tuoi ngModels.)


modificare

Come hai sottolineato, l’opzione ngInclude è molto meno utile quando si utilizza un servizio per restituire l’HTML.

Ecco il plunker modificato con una soluzione basata su direttive che utilizza $ compile, come nel commento di David sopra.

L’aggiunta pertinente:

 app.directive('customHtml', function($compile, $http){ return { link: function(scope, element, attrs) { $http.get('template.html').then(function (result) { element.replaceWith($compile(result.data)(scope)); }); } } }) 

Sulla base della risposta di Sarah, ho creato una struttura per mettere la direttiva

 .directive('dynamic', function(AmazonService, $compile) { return { restrict: 'E', link: function(scope, element, attrs) { AmazonService.getHTML() .then(function(result){ element.replaceWith($compile(result.data)(scope)); }) .catch(function(error){ console.log(error); }); } }; }); 

E nel codice HTML:

  

Grazie Sarah, ho aiutato tantissimo !!!

Ho un tavolo dinamico con qualche ng-repeat, poi quando ho provato a riempire una colonna con la funzione di callback javascript, mi ha dato solo testo html come

  "span class=someclass> some_text /span>"   "span class=someclass> some_text /span>"   "span class=someclass> some_text /span>"  

Così ho risolto il mio problema con jquery:

 $(".tableListFilas td").each(function(){ var td_class = $(this).attr("class"); if(td_class == 'tableList_'+titulo) { **var toExtraHtml = $(this).text();** **$(this).html(toExtraHtml);** } }); 

quindi l’output finale è stato buono:

  some_text   some_text   some_text