Angularjs 为模板提供表达式作为指令上的属性

Angularjs 为模板提供表达式作为指令上的属性,angularjs,angularjs-directive,Angularjs,Angularjs Directive,我想通过属性将“模板”传递到指令中。下面是一个老生常谈的例子,说明我正在努力实现的目标: 此HTML: <greeter person-name="Jim" greeting-template="Hello {{name}}"></greeter> 但是这不起作用,因为问候语模板属性中的{{{name}}在到达指令链接函数之前在父范围中进行求值 最后,我需要attrs.greetingTemplate的值实际上是一个字符串:“Hello{{name}”。我想我可以用一些

我想通过属性将“模板”传递到指令中。下面是一个老生常谈的例子,说明我正在努力实现的目标:

此HTML:

<greeter person-name="Jim" greeting-template="Hello {{name}}"></greeter>
但是这不起作用,因为
问候语模板
属性中的
{{{name}}
在到达指令链接函数之前在父范围中进行求值


最后,我需要
attrs.greetingTemplate
的值实际上是一个字符串:“Hello{{name}”。我想我可以用一些替代的语法来实现,比如将
问候语模板
属性值设置为:“Hello[name]”,并将“[”转换为“{{”在插值之前。但这感觉很混乱。我也看了transclusion,但它对父作用域的指令求值方式似乎在我有多个迎宾者时可能会导致问题。

您可以使用
链接
函数,而不是使用
编译
函数,该函数在链接到作用域之前运行发生,并将模板元素(原始DOM元素)及其不相关属性作为参数传递

compile
函数中,您可以将不相关的模板字符串存储在变量中,以供以后在
post link
函数中使用(如果使用
link
而不是
compile
,则与
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);
      }
    };
  }  
}
函数问候器($interpolate){
var指令={
编译:编译,
限制:“EA”,
范围:正确,
模板:“{{evaluatedTemplate}}”
};
返回指令;
函数编译(远程通讯、tAttrs){
//保存不相关的模板,以便在我们的post链接功能中使用
var greetingtemplateunterpolated=tAttrs.greetingTemplate;
返回{
pre:function(作用域、元素、属性){},
post:功能(范围、元素、属性){
scope.name=attrs.personName;
scope.evaluatedTemplate=$interpolate(GreetingTemplateUnterpolated)(范围);
}
};
}  
}
显示它的工作


这是一篇非常好的文章,解释了
编译
链接
的工作原理。

可以尝试在
问候者
元素上设置
ng non-bindable
属性,不仅可以防止对
问候模板
属性进行角度评估(好),还可以防止对整个指令进行评估(不好)。这不是答案。在html中使用不同的大括号,而不是
{}
,然后自己解析它们。或者使用一个options对象,然后从ControllerPooking传递给
链接
函数的其他对象中传递,我发现
元素.attr('greeting-template')
返回“Hello{{name}’。这正是我要寻找的。但在对对象没有更全面的了解的情况下,我担心是否会有我看不到的边缘情况。太好了!如果我能建议只做一个更改,它最好有自己的范围,无论是原型继承的还是孤立的。我建议对
范围:true
进行编辑。我完全同意格力。这也是我的想法,但因为它不在你最初的指令中,我不想在不知道你是否有具体理由遗漏它的情况下添加它。
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);
      }
    };
  }  
}