2014-07-04 14 views
6

Quello che voglio fare, è quello di gestire transclude a mano e modificare il contenuto prima di inserisco nel DOM:Come modificare il contenuto escluso prima di compilare all'interno della direttiva?

return { 
    restrict: 'E', 
    transclude: true, 
    template: '<HTML>', 
    replace: true, 
    link: function(scope, element, attrs, ngModelCtrl, $transclude) { 

     var caption = element.find('.caption'); 

     $transclude(function(clone) { 
      console.log(clone); 
      clone.filter('li').addClass('ng-hide'); // this don't work 
      clone.addClass('ng-hide'); // same this one 
      clone.attr('ng-hide', 'true'); // same this one 
      $compile(clone)(scope.$new()).appendTo(caption); 
      caption.find('li').addClass('ng-hide'); // and this 
     }); 
    } 
} 

In angular.js fonte ho trovato questo esempio:

var templateElement = angular.element('<p>{{total}}</p>'), 
     scope = ....; 

    var clonedElement = $compile(templateElement)(scope, function(clonedElement, scope) { 
    //attach the clone to DOM document at the right place 
    }); 

    //now we have reference to the cloned DOM via `clonedElement` 

ma quando aggiungo clonedElement.appendTo(caption); all'interno della funzione di collegamento, aggiunge solo commenti con ng-repeat all'interno.

Ho bisogno di questo perché ho bisogno di nascondere tutti gli elementi in questo caso

<dropdown> 
    <li ng-repeat="item in items"><a>{{item.label}}</a></li> 
</dropdown> 

ho bisogno di modificare il modello prima di compilare o DOM dopo ng-repeat è espanso. Prima sarebbe meglio, perché sarò in grado di aggiungere la logica usando la direttiva ng-hide invece della classe ng-hide.

risposta

3

jcubic. Non devi usare $ compilare per quello che stai cercando di fare.

È possibile filtrare l'elemento transclusa 'clone' e aggiungere classi CSS ai nodi filtrati, ma dopo che si deve accodare il clone modificato al modello (è identificato dall'attributo 'elemento' della funzione di collegamento) .

element.append(clone) 

Ho creato questo jsfiddle per voi.

Se avete ancora altre domande, si prega di creare un jsfiddle del vostro case.It Sarà meglio fare una risposta Thx

0

Se stai usando angolare> 1.3 e ngTransclude nel modello, quindi è necessario aggiornare non il clone, ma transclusa DOM, ad esempio:

elm.find('ng-transclude') 

http://jsfiddle.net/jhqkxgos/

ma essere sicuri di compile elementi trovati se si aggiorna alcuni è necessario accedere dal regolatore

3

Mi rendo conto che è passato molto tempo da quando è stata pubblicata questa domanda, ma spero che tu possa trovare utile quanto segue.

Sono stato piuttosto lungo e pesantemente in questa attività (di esclusione), ho provato alcuni modi per ottenere ciò di cui hai bisogno @jcubic e alla fine mi sono imbattuto in una soluzione davvero robusta e abbastanza semplice.

... 
replace: false, 
transclude: false, 
compile: function(tElement, tAttributes) { 

    // store your "transcluded" content of the directive in the variable 
    var htmlContent = tElement.html(); 
    // then remove it 
    tElement.html(''); 

    return function postLink(scope, elem, attrs) { 
     // then html var is available in your link! 
     var $html = $('<div />',{ html:htmlContent }); // for much easier manipulation (so you can use DOM functions - you can also manipulate directly on htmlContent string) 

     // so you can manipulate the content however you want 
     scope.myVariable = true; 
     $html.find('li').attr('ng-hide', 'myVariable'); // add native directive 
     $html.removeClass('inner-content').addClass('my-inner-content'); // add/remove class 
     $html.find('#myElement').attr('my-directive',''); // add custom directive etc. etc. 

     // after you finished you just need to compile your html and append your directive element - also however you want 
     // you also convert back $html to the string 
     elem.append($compile($html.html())(scope)); // append at the end of element 
     /* or: 
     elem.find('.my-insert-point').html($compile($html.html())(scope)); // append the directive in the specific point 
     elem.find('[my-transclude]').html($compile($html.html())($parent.scope)); // once the scope:true it will be the same as native transclusion ;-) 
     scope.variable = $html.html(); // or you can probably assign to variable and use in your template with bind-html-compile (https://github.com/incuna/angular-bind-html-compile) - may need $sce.trustAsHtml 
     */ 
    } 
} 
... 

Così come si può vedere di avere il pieno controllo sul suo sito web "transclusa" e non hai nemmeno bisogno di inclusione! :-)

ps. L'ho provato con Angular 1.4. Non sono sicuro che funzioni con replace: true (non ero preoccupato di testarlo perché è un fastidio secondario se non lo è). È possibile utilizzare il collegamento pre e post come normalmente si utilizzerà all'interno della funzione di compilazione e è necessario inserire il servizio $ compile nella direttiva.

Problemi correlati