-->

Using $attrs to evaluate attribute with curly brac

2019-07-05 20:30发布

问题:

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.

$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.

Next i tried using ng-attr-upload-url with and without using $eval on it.

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.

回答1:

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.

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. 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.

In your case you need to use $interpolate like below

In 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){

    }

  }

})


回答2:

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

    }
};

});