AngularJS:从控制器访问特定的指令范围 [英] AngularJS : Accessing particular directive scope from controller

查看:21
本文介绍了AngularJS:从控制器访问特定的指令范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 angular 的新手,所以如果我遗漏了任何内容或误解了文档,请原谅我.

我有一个指令,它将元素转换为 jquery 插件

.directive('myDir', function($compile) {返回 {链接:功能(范围,元素,属性){//$('.someDiv').jqueryPlugin(...);element.jqueryPlugin();var el = $compile("<span translate>{{ 'label' }}</span>")(scope);element.find('.label').html(el);}}})

如您所见,首先我在 html 元素中创建了一个 jquery 插件(它在元素内创建了它的 dom,包括一些带有标签类的 div - 假设它包含一些应该是动态的字符串,并且应该可以全局翻译)和然后我将静态 jquery 生成的标签替换为内插标签.我应该可以从控制器管理它.

问题是,我可以在一个控制器中包含多个指令,比如说

<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>

在指令和 jquery 运行之后,它会给出一些东西,比如,让我们说

<div class="label"><span>{{label|translate}}</span>

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

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

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

如何从控制器管理特定指令?如何访问所选范围的范围?

我认为

//控制器$scope.label = "一些内容";

将更改所有标签

有没有办法实现目标?或者我应该查看解决问题的方法吗?

提前致谢!

编辑

我还将拥有 dom 元素,这需要从控制器级别附加指令.它们也应该可以从这个级别进行维护.所以我的想法是提供一种服务,这将是某种带有 api 的外观,可以在 jquery-plugin'ed dom 元素上工作.

所以可以说我需要一些东西

.provider('facade', function() {this.$get = function($rootScope, $compile) {返回 {创建插件:函数(domElement,defaultLabel){domElement.attr('my-dir', defaultLabel);$compile(domElement)($rootScope);},更改标签(domElement,新标签){//获取提供的 dom 元素的 myDir 范围scope.label = newLabel;}}};})

它适用于 createPlugin,但不知道如何让 changeLabel 工作...

外观的最佳用法来自控制器:

toBePlugined = $('div.tbp');facade.createPlugin(toBePlugined, 'label');Facade.changeLabel(toBePlugined, 'label2');

我为什么需要这样的服务?因为我希望能够从脚本中的各个位置修改插件元素配置.可能包括各种 div、body 标签等.

现在 - 我的问题是通过提供其 dom 对象引用来访问指令范围.是否可以?我试图在 dom 对象上使用 my-dir 属性而没有效果.

解决方案

可以有多种方法来解决这个问题,这里有几种方法.您可以根据需要使用具有 2-way (=) 的隔离作用域指令 (scope:{}).您还可以使用 scope:true,即从指令创建一个子作用域(如果与 ng-repeat 一起使用,您甚至可以在没有作用域的情况下使用它,因为它已经创建了一个子作用域).但是,与具有自己的合同(隔离范围)的指令相比,这种方法的可重用性/灵活性较差.

因此您可以将指令更改为:

.directive('myDir', function($compile) {返回 {范围:{label:'=myDir'//设置2路绑定},链接:功能(范围,元素,属性){//$('.someDiv').jqueryPlugin(...);element.jqueryPlugin();var el = $compile("<span translate>{{ 'label' }}</span>")(scope);element.find('.label').html(el);}}});

并从您的控制器绑定,假设您有一个标签列表.

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

那么你可以这样做:

<div ng-repeat="标签中的项目" my-dir="item.label"></div>

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.

解决方案

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>

这篇关于AngularJS:从控制器访问特定的指令范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆