I'm new to angular, so forgive me if I missed anything or misunderstand the docs.

I have a directive, which converts the element to jquery plugin

.directive('myDir', function($compile) {
    return {
        link: function(scope, element, attributes) {
            // $('.someDiv').jqueryPlugin(...);
            element.jqueryPlugin();
            var el = $compile("<span translate>{{ 'label' }}</span>")(scope);
            element.find('.label').html(el);
        }
    }
})

as you can see, first I create a jquery plugin in html element (it creates its dom inside element, including some div with label class - lets say it contains some string that should be dynamic, and should be translateable globally) and then I replace static jquery-generated label to interpolated one. I should be able to manage it from controller.

the problem is, that I can have many directives in one controller, let's say

<div my-dir class="label-inside-1"></div>
<div my-dir class="label-inside-2"></div>
<div my-dir class="label-inside-3"></div>
<div my-dir class="label-inside-4"></div>

after directive and jquery is run it would give something, like, let's say

<div my-dir class="label-inside-1">
    <div class="label">
        <span>{{label|translate}}</span>
    </div>
</div>
<div my-dir class="label-inside-2">
    <div class="label">
        <span>{{label|translate}}</span>
    </div>
</div>
<div my-dir class="label-inside-3">
    <div class="label">
        <span>{{label|translate}}</span>
    </div>
</div>
<div my-dir class="label-inside-4">
    <div class="label">
        <span>{{label|translate}}</span>
    </div>
</div>

how, from the controller, can I manage a particular directive? how to access the scope for a chosen one?

i assume that

// controller
$scope.label = "some content";

is going to change all of the labels

is there a way to achieve the goal? Or should I review the approach to the problem?

thanks in advance!

EDIT

I will also have dom elements, that would need to have directive attached from the controller level. they should also be maintainable from this level. so my idea is to provide a service, that would be some kind of facade with api, that would work on jquery-plugin'ed dom elements.

so lets say I would need something

.provider('facade', function() {
    this.$get = function($rootScope, $compile) {
        return {
            createPlugin: function(domElement, defaultLabel) {
                domElement.attr('my-dir', defaultLabel);
                $compile(domElement)($rootScope);
            },
            changeLabel(domElement, newLabel) {
                // get a scope of myDir for provided dom element
                scope.label = newLabel;
            }
        }
    };
})

it works for createPlugin, but no idea how to get changeLabel working...

Best usage of the facade would be from controller:

toBePlugined = $('div.tbp');

facade.createPlugin(toBePlugined, 'label');
facade.changeLabel(toBePlugined, 'label2');

why do I need a service for that? because I want to be able to amend pluginned elements configuration from various places in the script. that could include various divs, body tag, etc.

and now - my problem is to access the directive scope by provading its dom object reference. is it possible? I was trying to play with my-dir attribute on dom object with no effect.

share|improve this question

There could be multiple ways to solve this, here are a couple of ways. You could use isolated scoped directive (scope:{}) with 2-way (=), based on how you need it. You could also use scope:true, i.e creating a child scope from the directive (if using with ng-repeat you can even use it with no scope since it already creates a child scope). But this approach would be less reusable/flexible as compared to the directive with its own contract(isolate scoped).

So you could change your directive to:

.directive('myDir', function($compile) {
    return {
        scope:{
           label:'=myDir' //Set up 2 way binding
        },
        link: function(scope, element, attributes) {
            // $('.someDiv').jqueryPlugin(...);
            element.jqueryPlugin();
            var el = $compile("<span translate>{{ 'label' }}</span>")(scope);
            element.find('.label').html(el);
        }
    }
});

and bind from your controller, say you have a list of labels.

 $scope.labels = [{label:'label1'}, {label:'label2'}, {label:'label3'}]

then you could just do:

<div ng-repeat="item in labels" my-dir="item.label"></div>
share|improve this answer
    
PSL, why would you use = here instead of &? Seems like that sets up an unnecessary watch. – Joe Enzminger Mar 11 '15 at 2:41
    
@JoeEnzminger I dont like the idea of using/hacking function binding (&) for explicitly bound property. Also note lets say it contains some string that should be dynamic, if you really want a one-time binding you could as well just use @ but that don't seem to be the purpose of OP. and well remember :: binding in 1.3+, removing unwanted watch is not really a problem that needs to be hacked with a different purpose implementation IMHO. And so why would u use = or @ because that is more appropriate to me than using & for this specific one. – PSL Mar 11 '15 at 2:44
    
I don't think that's correct (or that it is a hack). @ binding forces interpolation - which means the value will always be a string (you can't bind to objects with @). = creates an implicit watch on the directive scope value that modifies the corresponding parent scope expression if it is assignable. & creates a one way binding - which prevents the directive from modifying the parent scope - I think it is more than appropriate here. – Joe Enzminger Mar 11 '15 at 2:49
1  
Just like any other watch (that's why I like to minimize watches :). Check this out, using ::label you lose your dynamic properties. I think @ is indeed the correct way to go here. Just nitpicking. I agree with your quoted text - they are ideal for binding callback functions to directives, but that's not all they are ideal for. They are great for removing unnecessary watches as well and isolating directives from parent scopes ;) – Joe Enzminger Mar 11 '15 at 3:15
1  
@JoeEnzminger Yeah as i said earlier, better ways than using & because it can open another flood gate (I have had experience of that being misused when not used with purpose :( ).. Overall a good discussion though.. :) Thx!! – PSL Mar 11 '15 at 3:20

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.