使用 $attrs 评估其中带有花括号的属性

Using $attrs to evaluate attribute with curly braces in it

我正在创建一个使用以下标记的文件上传指令。

<file-upload
    name="myUploader"
    upload-url="{{$root.apiSettings.apiUrl}}/files"  
    auto-upload="true"
></file-upload>

我正在尝试像这样在指令控制器中获取 upload-url 属性。

$scope.uploadUrl = $attrs.uploadUrl

显然这是行不通的,因为我只是得到了带有 curly 大括号的未求值表达式。我尝试使用 $scope.$eval 来评估它,但我收到一个解析错误,指出 { was an invalid character at column 2.

接下来我尝试使用 ng-attr-upload-url 和不使用 $eval。

我通常会尽量避免使用隔离范围绑定,这可能会起到作用,因为我的指令中的大多数属性一次都是简单的,一种绑定方式,我想减少手表的数量,所以如果这可以使用简陋的 $attrs 集合来实现,我很想知道如何实现。

您可以通过下面显示的 link 函数访问指令的属性,您可以使用它来设置属性的值

main.directive('fileUpload', function () {
    return {
    ...
    link: function ($scope, elem, attr) {

        $scope.uploadUrl = attr.upload-url; //note attr.upload-url might cause problems, not sure if you can have dashed attribute names

    }
};

});

在指令中,范围绑定发生在 link 的较晚阶段,并且控制器执行得非常早,因此如果您想在指令的控制器中获取指令属性中提供的值,则需要在你的控制器中使用 $interpolate,考虑到你没有使用隔离范围。

要在控制器中获得正确的值,您可以使用 $parse$interpolate,具体取决于您通过指令的属性传递的内容。如果你只传递了 属性 的名称,那么你可以使用 $parse 否则如果你有一个内插字符串,你需要使用 $interpolate 它在给定的上下文中执行。

在你的情况下,你需要像下面这样使用 $interpolate

在HTML

  <body ng-app='app' ng-controller='mCTRL'>
    <h1>Hello Plunker!</h1>
    <file-upload
    name="myUploader"
    upload-url="{{url}}/files"  
    auto-upload="true"
     ></file-upload>
  </body>

您的指令应如下所示

app.directive('fileUpload',function(){

  return{
    restrict:'EA',
    controller:function($scope,$attrs,$interpolate){
     var myUrl=$interpolate($attrs.uploadUrl)($scope)
    },
    link(scope,elem,attrs,ctrl){

    }

  }

})

如果您将逻辑放在 link 函数而不是控制器中,那么传递给该 link 函数的 attrs 参数的 attrs.uploadUrl 已经为您进行了插值。这就是我建议如何解决您的问题,尽管 Rishi 提出的解决方案也可以。

app.directive('fileUpload', function() {
  return {
    restrict : 'EA',
    link : function(scope, elem, attrs) {
      var myUrl = attrs.uploadUrl;
    }
  };
});

我发现使用指令控制器而不是 link 函数的唯一原因是当我实际上想通过 require 属性 将该控制器注入另一个指令以促进交互时指令通信。

但是请注意,如果某些父指令定义了您希望在其自己的 post-link 函数中插入的范围属性,则它们将不会在后代的 post-link,因为那些 运行 从叶到根反向。如果您 运行 遇到那个问题,您应该使用 pre-link 函数在范围上定义此类属性,以便它们在您需要的地方可用。