简体   繁体   English

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

[英]Using $attrs to evaluate attribute with curly braces in it

I am creating a file upload directive which uses the following markup.我正在创建一个使用以下标记的文件上传指令。

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

I am trying to get the upload-url attribute in the directive controller like this.我正在尝试像这样在指令控制器中获取 upload-url 属性。

$scope.uploadUrl = $attrs.uploadUrl

Obviously this doesn't work as I just get the un-evaluated expression with the curly braces in it.显然这不起作用,因为我只是得到了带有花括号的未评估表达式。 I tried using $scope.$eval to evaluate it but I got a parse error saying { was an invalid character at column 2.我尝试使用 $scope.$eval 来评估它,但我得到一个解析错误,说 { 在第 2 列是一个无效字符。

Next i tried using ng-attr-upload-url with and without using $eval on it.接下来我尝试使用 ng-attr-upload-url 和不使用 $eval 。

I'm generally trying to avoid using isolate scope bindings which would probably do the trick because most of the attributes in my directives are simple one time, one way bindings and I want to cut down on the number of watches so if this can be achieved using the humble $attrs collection I'd love to know how.我通常试图避免使用隔离范围绑定,这可能会奏效,因为我的指令中的大多数属性都是简单的一次,一种方式绑定,我想减少手表的数量,所以如果可以实现的话使用不起眼的 $attrs 集合,我很想知道如何使用。

In directives scope binding happens at a very later stage in the link and the controller gets executed very early so if you want to get the values provided in attributes of the directive in your directive's controller you need to use $interpolate in your controller , considering you are not using isolated scope.在指令范围绑定发生在链接的非常晚的阶段,控制器很早就被执行,所以如果你想在指令的控制器中获取指令属性中提供的值,你需要在控制器中使用$interpolate ,考虑到你没有使用孤立的范围。

To get the proper value in the controller you can use either $parse or $interpolate depending upon what you have passed through your directive's attributes.要在控制器中获得正确的值,您可以使用$parse$interpolate具体取决于您通过指令的属性传递的内容。 If you passed just the name of the property then you can use $parse otherwise if you have an interpolated string you need to use $interpolate which gets executed in the given context.如果您只传递属性的名称,那么您可以使用 $parse 否则,如果您有一个内插字符串,您需要使用 $interpolate 在给定的上下文中执行。

In your case you need to use $interpolate like below在您的情况下,您需要使用 $interpolate 如下所示

In HTML在 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>

Your Directive should look like below您的指令应如下所示

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

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

    }

  }

})

You can access your directive's attributes through it's link function shown below, you can use this to set the value from the attribute您可以通过如下所示的链接函数访问指令的属性,您可以使用它来设置属性的值

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

    }
};

}); });

If you put your logic in a link function instead of a controller, then the attrs.uploadUrl passed to the attrs argument of that link function will already be interpolated for you.如果您将逻辑放在链接函数而不是控制器中,那么传递给该链接函数的 attrs 参数的 attrs.uploadUrl 将已经为您插入。 That is how I would recommend solving your problem, although the solution proposed by Rishi will work as well.这就是我建议解决您的问题的方式,尽管 Rishi 提出的解决方案也适用。

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

The only reason I have ever found to use a directive controller rather than a link function is when I actually want to inject that controller into another directive via the require property for facilitating inter-directive communication.我发现使用指令控制器而不是链接函数的唯一原因是当我实际上想通过 require 属性将该控制器注入另一个指令以促进指令间通信时。

Note however that if some parent directive defines scope properties you want interpolated in its own post-link function, they will not be defined yet in a descendant's post-link, as those run in reverse from leaf to root.但是请注意,如果某些父指令定义了您希望在其自己的 post-link 函数中插入的范围属性,它们将不会在后代的 post-link 中定义,因为这些属性从叶到根反向运行。 If you run into that issue you should use the pre-link function to define such properties on the scope so that they are available where you want them.如果您遇到该问题,您应该使用预链接功能在作用域上定义此类属性,以便它们在您需要的地方可用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM