提供带有表达式的模板作为指令的属性

时间:2016-06-02 00:31:20

标签: angularjs angularjs-directive

我想传递一个"模板"通过属性进入指令。这是我试图完成的一个例子:

此HTML:

<greeter person-name="Jim" greeting-template="Hello {{name}}"></greeter>

会产生输出:Hello Jim

我尝试过这样的指令:

function greeter($interpolate) {
    var directive = {
        link: link,
        restrict: 'EA',
        template: '<div>{{evaluatedTemplate}}</div>'
    };
    return directive;

    function link(scope, element, attrs) {
        scope.name = attrs.personName;
        scope.evaluatedTemplate = $interpolate(attrs.greetingTemplate)(scope);
    }
}

但这并不起作用,因为{{name}}属性中的greeting-template在获取指令链接函数之前在父作用域中得到评估。

最终,我需要将attrs.greetingTemplate 的值作为以下字符串:&#39; Hello {{name}}&#39;。我想我可以用一些替代语法来做,例如将greeting-template属性值设置为:&#34; Hello [name]&#34;转换&#34; [&#34;到&#34; {{&#34;在插值之前。但那感觉很麻烦。我也看了一下transclusion,但是它对 parent 范围的指令进行评估的方式看起来好像在我有多个欢迎时会引起问题。

1 个答案:

答案 0 :(得分:1)

您可以使用link函数代替使用compile函数,该函数在任何链接到范围之前运行,并且传递模板元素(原始DOM元素)以及它的非插值属性作为参数。我认为这就是你在这里寻找的东西。

compile函数中,您可以将未插入的模板字符串存储在变量中,以便以后在post-link函数中使用(如果使用{link函数,则与link函数相同{1}}而不是compile),然后您可以将其绑定到范围。

所以你的指令看起来像这样,带有compile属性而不是link属性:

function greeter($interpolate) {
  var directive = {
    compile: compile,
    restrict: 'EA',
    scope: true,
    template: '<div>{{evaluatedTemplate}}</div>'
  };
  return directive;

  function compile(tElement, tAttrs) {

    // save the uninterpolated template for use in our post-link function
    var greetingTemplateUninterpolated = tAttrs.greetingTemplate;

    return {
      pre: function (scope, element, attrs) {},
      post: function (scope, element, attrs) {
        scope.name = attrs.personName;
        scope.evaluatedTemplate = $interpolate(greetingTemplateUninterpolated)(scope);
      }
    };
  }  
}

Here's a fiddle显示它有效。

here's这是一篇非常好的文章,解释compilelink如何运作。