AngularJS - Access isolated scope in directive's link function

前端 未结 4 2103
北海茫月
北海茫月 2020-12-13 09:46

I\'m giving a first try at AngularJS custom directives.

I\'m having trouble using (or understanding ...) the isolated scope in the link function of the directive.

相关标签:
4条回答
  • 2020-12-13 09:51

    This is intentional and has to do with compilation order and the difference between '@' and '='.

    Some excerpts from this Google Groups discussion with input from Misko:

    @ and = do very different things. One copies the attribute value (which may be interpolated) and the other treats the attribute value as an expression.

    @attrs are not $interpolated until later, so they are not available at link time. If you want to do something with them in the link function you either need to $interpolate yourself manually

    0 讨论(0)
  • 2020-12-13 09:58

    well, none of the answers above actually mentioned one key aspect, even with '=', it doesn't seem to me you can access the scope inside link function directly like the following,

    scope: {
        data: '=',
    },
    link: function(scope, elem, attrs) {
        console.debug(scope.data); // undefined
    

    but you can access the scope in the internal function,

    link: function(scope, elem, attrs) {
        scope.saveComment = function() {
            console.debug(scope.data);
    

    so it seems to me there might be a time lag in when scope.data can be available.

    0 讨论(0)
  • 2020-12-13 10:10

    You can visit the JSFiddle created by me here: http://jsfiddle.net/7t984sf9/5/:

    link: function($scope, $elem, $attr) {
        console.log($scope.onewayObject);
        $attr.$observe('onewayObject', function(value) {
             console.log(value);
        });
    }
    

    Or some more detailed explanation here: What is the difference between & vs @ and = in angularJS

    0 讨论(0)
  • 2020-12-13 10:11

    Isolate scope properties bound with @ are not immediately available in the linking function. You need to use $observe:

    $attr.$observe('id', function(value) {
       console.log(value);
    });
    

    Your template works properly because Angular automatically updates isolate scope property id for you. And when it does update, your template automatically updates too.

    If you are just passing strings, you can simply evaluate the values once instead of using @ binding:

    link: function($scope, $elem, $attr) {
        var id    = $attr.id;
        var title = $attr.title
        console.log(id, title);
    }
    

    However, in your case, since you want to use the properties in templates, you should use @.

    If you weren't using templates, then @ is useful when attribute values contain {{}}s – e.g., title="{{myTitle}}". Then the need to use $observe becomes more apparent: your linking function may want to do something each time the value of myTitle changes.

    0 讨论(0)
提交回复
热议问题