Hi Aaron,

I'll give it my best shot at explaining, although I don't claim to be a 
angular guru. 

When the directive is initialized, wouldn't the scope also be set?
>


The 'initialization' of a directive is a two-step process.  First the 
compilation phase, then the linking phase.  The linking phase (which we 
have hooked into with our link function) is called once per instance of the 
draggable directive.  Since our draggable directive is within a ng-repeat, 
we end up with 3 instances.

In terms of which scope is passed to the instance of the our directive, we 
also need to remember that we are operating within an ng-repeat.  From the 
docs:

*The ngRepeat directive instantiates a template once per item from a 
collection. Each template instance gets its own scope*


Perhaps this plnkr <http://plnkr.co/edit/vJnPQH?p=preview> is a better 
example.  In this example the directive provides the template which 
replaces the original element on which the directive is defined.  The 
draggable directive is still defined with an isolate scope.
We end up with the following scope hierarchy:

App Scope
   |--- Ctrl Scope
            |--- NgRepeat scope
                  |--- Draggable scope
            |--- NgRepeat scope
                  |--- Draggable scope
            |--- NgRepeat scope
                  |--- Draggable scope

All the scopes inherit from each other *except* the Draggable scope.  This 
scope is an isolate scope, so although conceptually it is a child of the 
ngRepeat scope, it doesn't inherit values from it, which is why I had to 
pass in a binding to the song element being referred to by the current-song 
attribute in html:

        scope: {
            song: "=currentSong"
        },

Notice that the directive template doesn't have access to the playlist on 
the scope (i.e. it is isolated) - which is why we don't see the playlist 
value

Now, if we were to remove the isolate scope - i.e. comment out:

//        scope: {
//            song: "=currentSong"
//        },

... then the draggable directive's scope would be the same as the scope 
created by the ng-repeat (since it is defined on the same element), and we 
end up with a scope hierarchy as follows (all inherit from one another):


App Scope
   |--- Ctrl Scope
            |--- NgRepeat & Draggable scope
            |--- NgRepeat & Draggable scope
            |--- NgRepeat & Draggable scope
       
and  in this case the playlist is visible to the directive's scope.

-


On Tuesday, October 7, 2014 4:02:38 PM UTC+2, Aaron Hatch wrote:
>
> Justin, that appears to work. I'm wondering why, though. When the 
> directive is initialized, wouldn't the scope also be set? It seems like 
> scope is fluid in that changes to the DOM after the directive is set are 
> updated in the scope.
>
> Either way, thank you!
>
>
> On Tuesday, October 7, 2014 12:55:39 AM UTC-5, Justin Walsh wrote:
>>
>> Hi Aaron
>>
>> Something like this <http://plnkr.co/edit/lVtrMj> ?
>>
>> (I haven't added the class based on the ownership, but that should be 
>> trivial)
>>
>> Justin
>>
>> On Tuesday, October 7, 2014 3:20:34 AM UTC+2, Aaron Hatch wrote:
>>>
>>> I use ng-repeat to present a list of songs. I use ng-class to determine 
>>> which songs should have a "song-unavailable" class. I also have a draggable 
>>> directive for jQuery UI.
>>>
>>> <li ng-repeat="song in songs" ng-class="{'song-unavailable' : song.owned 
>>> === true}"  draggable>
>>>
>>> myApp.directive('draggable', function() {
>>>         return {
>>>             restrict:'A',
>>>             link: function(scope, element, attrs) {
>>>                     element.draggable({
>>>                         revert: false,
>>>                         helper: 'clone',
>>>                         appendTo: '#my_table',
>>>                         zIndex:1000,
>>>                         cursorAt: { left: 50 },
>>>                         start: function(event, ui) {
>>>                             $('body').css('cursor', 'move');
>>>                         },
>>>                     });
>>>             }
>>>         };
>>> });
>>>
>>> Here's the problem: I only want songs to be draggable if song.owned === 
>>> true. However, the directive is initialized before the ng-class expression 
>>> is evaluated. So, all songs have the directive and are draggable. What can 
>>> I do to prevent songs that aren't owned to not be draggable?
>>>
>>

-- 
You received this message because you are subscribed to the Google Groups 
"AngularJS" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/angular.
For more options, visit https://groups.google.com/d/optout.

Reply via email to