AngularJS: accessing a specific scope of a directive from a controller

I am new to angular so forgive me if I missed anything or misunderstood the docs.

I have a directive that converts an element to a 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 an html element (it creates its inner element inside, including some div with a label class - lets say it contains some string that should be dynamic and should be globally translatable) and then I replace the old jquery-generated label with an interpolated one. I need to be able to control it from the controller.

the problem is that i can have many directives in one controller, 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 the directive is run and jquery it will give something like let

<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 a controller, can i control a specific directive? how to access the area for the selected one?

i suppose that

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

      

going to change all labels

Is there a way to achieve the goal? Or should I consider approaching the problem?

early!

EDIT

I will also have dom elements that need to have a directive attached from the controller level. they must also be supported from this level. so my idea is to provide a service that will be some kind of facade with an api that will work with the jQuery-plugin 'house elements.

so let's say I 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 dont know how to get changeLabel to work ...

The best use of the facade would be from the controller:

toBePlugined = $('div.tbp');

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

      

why do i need a service? because I want to be able to change the configuration of the plugin items from different places in the script. which can include various divs, body tags, etc.

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

+1


source to share


1 answer


There may be several ways to solve this problem, here are several ways. You can use the dedicated bounded directive ( scope:{}

) with two-way ( =

), based on how you need it. You can also use scope:true

, i.e. Create child scope from directive (if you are using with ng-repeat, you can even use it without scope as it already creates child scope). But this approach would be less reusable / flexible compared to the directive with its own contract (isolate scope).

So you can 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 to your controller, let's say you have a list of labels.



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

      

then you can simply do:

<div ng-repeat="item in labels" my-dir="item.label"></div>

      

+2


source







All Articles