2013-01-16 10 views
8

Proszę mi pomóc, w jaki sposób możemy sprawić, że AngularJS skompiluje kod wygenerowany przez dyrektywę?Jak zmusić AngularJS do kompilacji kodu wygenerowanego przez dyrektywę?

Można nawet znaleźć ten sam kod tutaj http://jsbin.com/obuqip/4/edit

HTML

<div ng-controller="myController"> 
    {{names[0]}} {{names[1]}} 
    <br/> <hello-world my-username="names[0]"></hello-world> 
    <br/> <hello-world my-username="names[1]"></hello-world> 
    <br/><button ng-click="clicked()">Click Me</button> 
</div> 

JavaScript

var components= angular.module('components', []); 
components.controller("myController", 
    function ($scope) { 
     var counter = 1; 
     $scope.names = ["Number0","lorem","Epsum"]; 
     $scope.clicked = function() { 
      $scope.names[0] = "Number" + counter++; 
     }; 
    } 
); 

// **Here is the directive code** 
components.directive('helloWorld', function() { 
    var directiveObj = { 
     link:function(scope, element, attrs) { 
      var strTemplate, strUserT = attrs.myUsername || ""; 
      console.log(strUserT); 
      if(strUserT) { 
       strTemplate = "<DIV> Hello" + "{{" + strUserT +"}} </DIV>" ; 
      } else { 
       strTemplate = "<DIV>Sorry, No user to greet!</DIV>" ; 
      } 
      element.replaceWith(strTemplate); 
     }, 
     restrict: 'E' 
    }; 
    return directiveObj; 
}); 

Odpowiedz

14

Oto wersja, która nie korzysta z funkcji kompilacji ani funkcji Link:

myApp.directive('helloWorld', function() { 
    return { 
    restrict: 'E', 
    replace: true, 
    scope: { 
     myUsername: '@' 
    }, 
    template: '<span><div ng-show="myUsername">Hello {{myUsername}}</div>' 
    + '<div ng-hide="myUsername">Sorry, No user to greet!</div></span>', 
    }; 
}); 

Zauważ, że szablon jest zawinięty w rozpiętości <> dlatego, że szablon musi mieć jeden element główny. (Bez przęsła <>, to dwa < div> korzeniowe).

HTML musi być nieznacznie zmodyfikowany, aby interpolować:

<hello-world my-username="{{names[0]}}"></hello-world> 

Fiddle.

+0

To jest świetny kawałek kodu! – SunnyShah

+0

Czy wiązanie "=" nie byłoby bardziej odpowiednie? http://jsfiddle.net/979mN/1/ –

+7

@Liviu, ponieważ dyrektywa nie zmienia wartości myUsername, jednokierunkowe wiązanie danych ("@") wydaje się bardziej odpowiednie niż dwukierunkowe wiązanie danych ("="). Chociaż używanie '=' jest łatwiejsze (nie trzeba używać {{}} w HTML), użycie '@' wyjaśnia, że ​​dyrektywa nie musi modyfikować wartości. –

9

Musisz utworzyć kątowy element z szablonu i wykorzystania usługa $compile

jsBin

components.directive('helloWorld', ['$compile', function(compile) { 
    var directiveObj = { 
     link: function(scope, element, attrs) { 
      var strTemplate, strUserT = attrs.myUsername || ""; 
      console.log(strUserT); 
      if (strUserT) { 
       strTemplate = "<DIV> Hello" + "{{" + strUserT +"}} </DIV>" ; 
      } else { 
       strTemplate = "<DIV>Sorry, No user to greet!</DIV>" ; 
      } 

      var e = angular.element(strTemplate); 
      compile(e.contents())(scope); 
      element.replaceWith(e); 
     }, 
     template: function() { 
      console.log(args); 
      return "Hello"; 
     }, 
     restrict: 'E' 
    }; 
    return directiveObj; 
}]); 
+0

Wielkie dzięki. Jak się tego nauczyłeś? – SunnyShah

+0

Dodano inny sposób, aby to zrobić, http://jsbin.com/obuqip/9/edit – SunnyShah

+0

http://stackoverflow.com/questions/12164138/what-is-the-difference-between-compile-and-link- funkcja-in-angularjs. Zwykle nie jest to problem z dyrektywą 1: 1: html. Polecenia ng-repeat i podobne wykorzystują funkcję kompilacji do optymalizacji. –

10

Kod: http://jsbin.com/obuqip/9/edit

components.directive('helloWorld', function() { 
    var directiveObj = { 
     compile:function(element, attrs) { 
      var strTemplate, strUserT = attrs.myUsername || ""; 
      console.log(strUserT); 
      if(strUserT) { 
       strTemplate = "<DIV> Hello " + "{{" + strUserT +"}} </DIV>" ; 
      } else { 
       strTemplate = "<DIV>Sorry, No user to greet!</DIV>" ; 
      } 
      element.replaceWith(strTemplate); 
     }, 
     restrict: 'E' 
    }; 
    return directiveObj; 
}); 

Objaśnienie: Ten sam kod powinien być stosowany w funkcji kompilacji niż funkcja łączenia. AngularJS kompiluje wygenerowaną zawartość funkcji kompilacji.

+0

Ponieważ 'element' nie jest używany w wersji funkcji Link tej dyrektywy (odpowiadający Liviu), zgadzam się że funkcja kompilacji wydaje się lepsza. –

+0

Właśnie napisałem odpowiedź, która nie wymaga nawet funkcji kompilacji. –

+0

Oznaczono jako odpowiedź. – SunnyShah

Powiązane problemy