Ho provato a creare la mia direttiva ricorsiva con AngularJS, che si chiama per trasformare un oggetto in una vista con un bel formato JSON. Bene, per prima cosa ho usato un ng-include che chiamava uno script con il modello, con un ng-se al suo interno verificando se il valore corrente fosse un oggetto, se così fosse, la chiamata al modello stessa.
Penso sempre che questo sia un modo ungly per farlo, quindi mi trasformo in una direttiva, molto più semplice.
Sempre di più ... Perché scopro il mondo delle direttive ricorsive e ho trovato molte cose e più interessanti. Ho anche dato una lettura nel codice sorgente di Angular in github (ti consiglio di leggere: https://github.com/angular/angular.js), con era una buona cosa.
Ho cercato così duramente, e penso che sto quasi trovando l'awser che adorerà il mio cuore! Perché imparo molte nuove cose e voi ragazzi, mi aiuterete.
Guarda il mio codice nel link qui sotto: https://github.com/Daymannovaes/htmljs/blob/master/js/directives/recursiveDataTemplateDirective.js
mia direttiva sono: ricorsiva-data-template = "data", in cui i dati sono un oggetto. Questa direttiva eseguirà un loop sulla chiave e sui valori di questo oggetto e, se il valore fosse un oggetto, lo farà di nuovo. Le condizioni sono fatte con ng-if = "isObject (valore)".
Ok, il mio primo problema era il ciclo infinito. Devo rimuovere il contenuto nella fase di compilazione e quindi compilare imperativamente il contenuto nella fase postLink. La mia domanda: ** Perché la compilazione manuale non cade sullo stesso problema del ciclo infinito? **
Sto compilando lo stesso contenuto, nessuna condizione è stata creata (se if (! CompiledContent) è stata rimossa, il ciclo infinito non si verifica ancora), la differenza (credo) sono solo in malafede posto, ma non ero in grado di trovare in internet qualcuno che la mia domanda terribile!
Quindi, grazie! (se il link non funzionante, ecco il codice importante):
compile: function(templateElement, templateAttributes) { /* in compile time, we need to remove the innerHTML of template(url) because of its recursive. Because of its recusiveness, when the $compile start to read the DOM tree and find a recursiveDataTemplate directive (even its not will be evaluated all time by link function because the ng-if, whatever) its start the do all the process again. So, we need the .remove() */ var templateDirectiveContent = templateElement.contents().remove(); var compiledContent; return function($scope, linkElement, linkAttributes) { /* This verification avoid to compile the content to all siblings, because when you compile the siblings, don't work (I don't know why, yet). So, doing this we get only the top level link function (from each iteration) */ if(!compiledContent) { compiledContent = $compile(templateDirectiveContent); } /* Calling the link function passing the actual scope we get a clone object wich contains the finish viewed object, the view itself, the DOM!! Then, we attach the new dom in the element wich contains the directive */ compiledContent($scope, function(clone) { linkElement.append(clone); }); }; }, }
<ul>
<li data-ng-repeat="(key, value) in fields">
<span data-ng-if="!isNumber(key)">
{{key}}:
</span>
<span data-ng-if="isObject(value)" recursive-data-template="value"></span>
<span data-ng-if="!isObject(value)">
{{value}}
</span>
</li>
</ul>
Dai un'occhiata alla: https://github.com/dotJEM/angular-tree, io personalmente non credo che la vostra idea iniziale di ricorsiva ng-include sono un tale cattiva idea, tieni presente che puoi estrapolare quell'idea a un insieme di direttive, che è esattamente ciò che fa l'albero-punto-punto-ad-albero. Penso che sia logico avere una coppia di direttive, una che definisce un punto di partenza, quindi una che si collega in modo ricorsivo, in quanto ciò ti permetterà di fare dell'albero nell'albero, senza che siano in conflitto tra loro. http://plnkr.co/edit/uaZVzUhPsDIsx93kzXSP?p=preview – Jens
Questa è una domanda molto buona e mi dispiace che non sia stata fornita una buona risposta. – erilem
Ero di fronte allo stesso problema e lo risolvo usando il suggerimento 'compiledContent'. Inoltre, non capisco davvero perché, mi piacerebbe che spiegazioni ufficiali accurate su tutte queste cose funzionassero. – floribon