2014-10-09 60 views
3

我需要呈現一個角度指令,通過吸引先前在變量中定義的字符串(通常在控制器中聲明)來選擇它。儘管有這樣的一個變量是作爲一個角式訪問,當我嘗試使用選擇指令它不工作:選擇指令的角度表達式

<!DOCTYPE html> 
<html ng-app="app"> 
<body ng-controller="TextController"> 

<!-- item.dir is accessible: --> 
<div>Value of item: {{item.dir}}</div> 

<!-- It works. the directive "hello" is rendered --> 
<div class="hello"></div> 
<hello></hello> 

Here you should see additional text: 
<!-- Doesn't work item.dir is not recognized--> 
<!-- as a class --> 
<div class="{{item.dir}}"></div> 

<!-- as an attribute--> 
<div {{item.dir}}></div> 

<!-- trying ng-class (it fails)--> 
<div ng-class="item.dir"></div> 

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-rc.5/angular.min.js"></script> 

<script> 

    var appModule = angular.module('app', []); 

    // The directive to render 
    appModule.directive('hello', function() { 
     return { 
      restrict: 'ACE', 
      template: '<div>works: Transcoded text</div>', 
      replace: true 
     }; 
     }); 

    appModule.controller('TextController', function ($scope) { 
    $scope.item = {dir: 'hello'}; // the name of the directive, the idea is to use it for referring to many future directives. 
    }); 
</script> 
</body> 
</html> 

下面的代碼的plunker:http://plnkr.co/edit/tM73sY3vTfPFHmn6iCYE?p=preview

所以,我是什麼失蹤?如何在使用指令時使用字符串插值來獲得Angular?謝謝!

+0

這是爲什麼downvoted?我真的好奇爲什麼這不起作用。如果你要冷靜下來,至少要提供一個理由? – 2014-10-09 03:44:42

回答

2

對於指令的工作,Angular需要編譯你的html(當頁面被加載時會自動完成)。

有一種方法可以自由控制實例化哪個指令有點像拉下你腳下的地毯,並且是非典型的。其中一個問題是編譯「銷燬」內部綁定/觀察者數據和一些原始DOM,因此沒有足夠的信息來「重新編譯」DOM節點。注意:你不能使用這種類型的綁定來改變屬性或元素名稱(只有屬性值)的角度:{{}}但是ng-class =「...」和class =「{{...} }「的作品。

我不明白你想達到什麼目的。如果意圖是修改item.dir的價值並讓Angular「重新配置」你的應用程序,這是「可能的」,但我高度懷疑它會引起「狀態」缺陷。不過,這裏有一個「記住」原始DOM html的工作「黑客」,並在需要時重新編譯它。這是在兩個編譯階段完成的:第一階段是恢復原始綁定,第二階段在$ digest循環之後運行,以便原始綁定完成從作用域填充類名(即使item.dir有效)。當然,缺點是如果你對封裝的DOM進行了修改,這將會把它們擦掉!或者,可能只記住特定的屬性,只有在保持DOM的其他部分完好(但可能會產生其他問題)的同時還原「那個」。

appModule.directive('forceRecompilation', ['$timeout', '$compile', function($timeout, $compile) { 
    return { 
     restrict: 'A', 
     link: function(scope, element, attr) { 

     var originalHtml = element.html(); 

     scope.$watch(attr.forceRecompilation, function(){ 
      // restore original HTML and compile that 
      element.html(originalHtml); 
      $compile(element.contents())(scope); 

      // wait for all digest cycles to be finished to allow for "binding" to occur 
      $timeout(function(){ 
       // recompile with bounded values 
       $compile(element.contents())(scope); 
      }); 
      }); 
     } 
    }; 
    }]); 

...被用作要對其起作用的DOM部分的封閉標籤。當表達式改變時,它將「恢復&重新編譯」下面的所有內容。 (這裏 「item.dir」):

<div force-recompilation="item.dir"> 
    <div class="{{item.dir}}"> 
</div> 

Plunker:http://plnkr.co/edit/TcMhzFpErncbHSG6GgZp?p=preview

在plunker,有2個指令 「你好」 和 「hello2」。將文本更改爲「hello」並返回「hello2」以查看效果。

編輯:下面是一個指令,允許按照下面的註釋中所述插入標記進行編譯。這只是Angularjs - inline directives with ng-bind-html-unsafe

angular.module('bindHtmlExample', ['ngSanitize']) 
 
    .controller('ExampleController', ['$scope', 
 
     function($scope) { 
 

 
     $scope.test = false; 
 
     $scope.dir = "ng-click"; 
 
     $scope.clicked = function() { 
 
      $scope.test = !$scope.test 
 
     } 
 

 
     $scope.myHTML = 
 
      'I am an <b ng-show="test">invisible</b> HTML string with ' + 
 
      '<a href="#" ' + $scope.dir + '="clicked()">links!</a> and other <em>stuff</em>'; 
 
     } 
 
    ]) 
 

 
    // modified plunker taken from https://stackoverflow.com/questions/18063280/angularjs-inline-directives-with-ng-bind-html-unsafe 
 
    // 
 
    // Allows an attribute's value to be evaluated and compiled against the scope, resulting 
 
    // in an angularized template being injected in its place. 
 
    // 
 
    // Note: This directive is prefixed with "unsafe" because it does not sanitize the HTML. It is up 
 
    // to the developer to ensure that the HTML is safe to insert into the DOM. 
 
    // 
 
    // Usage: 
 
    //  HTML: <div unsafe-bind-html="templateHtml"></div> 
 
    //  JS: $scope.templateHtml = '<a ng-onclick="doSomething()">Click me!</a>'; 
 
    //  Result: DIV will contain an anchor that will call $scope.doSomething() when clicked. 
 
    .directive('unsafeBindHtml', ['$compile', 
 
    function($compile) { 
 
     return function(scope, element, attrs) { 
 
     scope.$watch(
 
      function(scope) { 
 
      // watch the 'compile' expression for changes 
 
      return scope.$eval(attrs.unsafeBindHtml); 
 
      }, 
 
      function(value) { 
 
      // when the 'compile' expression changes 
 
      // assign it into the current DOM element 
 
      element.html(value); 
 

 
      // compile the new DOM and link it to the current 
 
      // scope. 
 
      // NOTE: we only compile .childNodes so that 
 
      // we don't get into infinite loop compiling ourselves 
 
      $compile(element.contents())(scope); 
 
      } 
 
     ); 
 
     }; 
 
    } 
 
    ]);
<!doctype html> 
 
<html lang="en"> 
 

 
<head> 
 
    <meta charset="UTF-8"> 
 
    <title>Example</title> 
 

 

 
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.0-rc.5/angular.min.js"></script> 
 
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.0-rc.5/angular-sanitize.js"></script> 
 
    <script src="script.js"></script> 
 

 

 

 
</head> 
 

 
<body ng-app="bindHtmlExample"> 
 
    <div ng-controller="ExampleController"> 
 
    <p unsafe-bind-html="myHTML"></p> 
 

 
    (click on the link to see <code>ng-click</code> in action) 
 
    </div> 
 
</body> 
 

 
</html>

+0

你爲什麼說是非典型的?例如,你如何讓用戶動態添加字段到表單? (假設每個字段對應一個指令),當然如果你有一套有限的指令,隱藏/顯示可以做到這一點,但這不是問題的想法。 – fariza 2014-10-09 12:33:59

+0

支持經常使用的情況,例如動態添加自定義字段到表單。 這可能是關於添加/替換/刪除「標記」(通過指令內的模板,用ng-bindHtml重複執行)。什麼是非典型的是有已經加載的標記,然後去修改「其性質」(交換哪些指令正在爲特定元素正在加載)。這不是不可能的,而不是框架是如何構建的。 – Bernard 2014-10-09 15:55:18

+0

對不起,我以前的評論中有一個關於ng-bindHtml的錯誤(ng-bindHtml會淨化html,因此不會真的$編譯任何東西),您可以使用像這裏描述的自定義指令: http:// stackoverflow.com/questions/18063280/angularjs-inline-directives-with-ng-bind-html-unsafe 這裏是一個修改後的Plunker,它將編譯標記插入到DOM中,並帶有一個指令動態屬性。 (ng-click) http://plnkr.co/edit/WQScvFqdbeYdNE9ROR7X?p=preview – Bernard 2014-10-09 16:19:30