【问题标题】:Provide template with expressions as attribute on directive提供带有表达式的模板作为指令的属性
【发布时间】:2016-06-02 00:31:20
【问题描述】:

我想通过属性将“模板”传递给指令。这是我想要完成的一个老生常谈的例子:

这个 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);
    }
}

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

最终,我需要attrs.greetingTemplate 的值字面意思是一个字符串:'Hello {{name}}'。我想我可以用一些替代语法来做到这一点,比如将greeting-template 属性值设置为:“Hello [name]”并在插值之前将“[”转换为“{{”。但这感觉很乱。我也查看了嵌入,但是它根据 parent 范围评估指令的方式看起来可能会在我有多个问候语时引起问题。

【问题讨论】:

  • 在greeter 元素上设置ng-non-bindable 属性不仅可以防止greeting-template 属性被Angular 评估(好),它还可以防止整个指令被评估(坏)。所以这不是答案。
  • 在 html 中使用不同的大括号而不是 {{}} 并自己解析它们。或者使用选项对象并从控制器传入
  • 查看传递给link 函数的其他对象,我发现element.attr('greeting-template') 返回'Hello {{name}}'。这正是我正在寻找的。但是如果没有对对象有更完整的了解,我很担心是否有任何我没有看到的边缘情况。

标签: angularjs angularjs-directive


【解决方案1】:

您可以使用compile 函数而不是使用link 函数,该函数在任何到范围的链接发生之​​前运行,并通过模板元素(原始DOM 元素)以及它的未插值属性作为论据。我认为这就是您要在这里寻找的。​​p>

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

所以你的指令看起来像这样,带有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 是一篇非常好的文章,解释了 compile 和 link 的工作原理。

【讨论】:

  • 太棒了!如果我只能建议一项更改,最好有自己的范围,无论是原型继承还是隔离。我建议对 scope: true 进行编辑。
  • 我完全同意。这也是我的想法,但由于它不在您的原始指令中,我不想在不知道您是否有特定原因将其省略的情况下添加它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-02
  • 1970-01-01
  • 2015-06-01
  • 1970-01-01
  • 2012-12-08
相关资源
最近更新 更多