AngularJS:从控制器访问特定的指令范围

时间:2015-03-11 01:39:27

标签: javascript jquery angularjs angularjs-directive

我是棱角分明的新人,如果我错过了任何内容或误解了文档,请原谅我。

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

.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);
        }
    }
})

正如你所看到的,首先我在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 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>

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

我认为

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

将改变所有标签

有没有办法实现这个目标?或者我应该检讨问题的解决方法吗?

提前感谢!

修改

我还将拥有dom元素,需要从控制器级别附加指令。它们也应该从这个层面维持。所以我的想法是提供一种服务,这将是api的某种外观,可以用于jquery-plugin的dom元素。

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

.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;
            }
        }
    };
})

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

立面的最佳用途是来自控制器:

toBePlugined = $('div.tbp');

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

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

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

1 个答案:

答案 0 :(得分:2)

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

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

.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);
        }
    }
});

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

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

然后你可以这样做:

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