2014-10-09 71 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