When do isolated scope properties actually get added to the scope?

I'm creating some directives with an isolated scope and some aliased properties. For example:

scope: {
   prop1: '@'
}

My question is, when exactly to these aliases get added to the scope? I was running into some issues with the properties not being defined in my link function. Look in the console after running this jsFiddle: http://jsfiddle.net/rvd6x/.

When I try to get the property as normal it is not defined. If I try to get it later through a function (doStuff()) it is there. Or if I do a $timeout with 0 it is there. Obviously I can workaround my issues by using the $timeout, but I want to know why I can't just expect the scope to already have it right away in the link function. It'd be kind of a pain to have to inject $timeout throughout all my directives.

Answers:

Answer

I found that this works inside the directive definition:

scope: {
    prop1: '@'
},
link: function(scope, element, attrs) {
    ...
    attrs.$observe('prop1', function(val) { 
        scope.prop1 = val || 'default'
    });
    ...
}

to make

<div my-directive></div>

behave like

<div my-directive prop1="default"></div>
Answer

Here's my understanding: In general in a directive, you can not assume that any variable in a scope is defined or has a stable value. You need to $watch anything that's of interest to you.

Think of ng-repeat - the thing that you're repeating on might not exist at link time, it might change often, etc. - it's up to the directive to handle those scenarios.

Now I know that doesn't answer your question - you're creating an isolated scope which is explicitly setting a scope value, so intuitively what you're doing is different than the ng-repeat example. But it looks like Angular treats them the same and this is probably a good thing.

Depending on what you need to use the attribute for I think you can solve your problem in two ways:

  1. If it's an evaluated value and it might change, wrap it in a watch so you can react.
  2. If it's a static value you can use attrs.prop1 and pull it down at the beginning of your link fn.

Both of these options I've added to the fiddle here.

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.