AngularJS:在具有隔离范围的两个指令之间共享控制器范围

时间:2014-07-19 04:14:40

标签: javascript angularjs angularjs-directive angularjs-scope angularjs-controller

我有两个指令,它们对同一组数据提供不同的视图。这两个指令都需要依赖控制器中包含的中央功能。控制器使用各种服务为网格或馈送视图加载项目,执行搜索等。

我想在两个指令之间共享单个控制器。我意识到我可以通过使用ng-controller在两个指令上方的dom中指定控制器来实现此目的。但是,我不能让它工作,因为两个指令都要求将配置对象传递给它们(最好是通过隔离范围),中央控制器使用它。

我不能简单地在每个指令中指定控制器,因为angularjs控制器不是单例。通过这样做,将有两个控制器实例,因此有两组数据,手表等。

以下是一个示例情况。

HTML

<!-- myConfigObject comes from a scope above ListingController -->
<div data-ng-controller="ListingController">
    <div data-dir1 data-config="myConfigObject"></div>
    <div data-dir2 data-config="myConfigObject"></div>
</div>

控制器:

.controller('ListingController',
    function ($scope) {
        //Try to use $scope.config here and get errors because it's being passed in on 
        //children dom elements

        //These items need to be used in the templates provided in the directives sharing
        //this controller
        $scope.items = [
            {name:'test1'},
            {name:'test2'}
        ];
    }
);

指令:

.directive('dir1',
    function() {
        return {
            templateUrl: 'someTemplateThatUsesStuffOnControllerScope.html',
            scope: {
                config: '='
            }
        }
    }
)
.directive('dir2',
    function() {
        return {
            templateUrl: 'someOtherTemplateThatUsesStuffOnControllerScope.html',
            scope: {
                config: '='
            }
        }
    }
)

someTemplateThatUsesStuffOnControllerScope.html

<ul>
    <li data-ng-repeat="item in items">{{item.name}}</li>
</ul>

最后,我想要使用隔离范围,以保护其他父范围不会出现可能的&#34; $ scope.config&#34;被指令&#39;

覆盖

希望对所有人都有意义并希望有答案。

1 个答案:

答案 0 :(得分:0)

您可以为两个指令使用通用控制器。以下示例创建两个隔离指令,该指令使用名为 ControllerOfDir1Dir2 的公共控制器。

var app = angular.module('app', []);
app.controller('TestController', ['$scope', function($scope){}]);

app.directive('dir1', function(){
    return {
        restrict: 'EA',
        template: '<div>Sample text of dir1</div>',
        scope: {},
        link: ControllerOfDir1Dir2
    };
});

app.directive('dir2', function(){
    return {
        restrict: 'EA',
        template: '<div>Sample text of dir2</div>',
        scope: {},
        link: ControllerOfDir1Dir2
    };
});

function ControllerOfDir1Dir2(scope, element, attr){
    // You can get the node name (dir1 or dir2) using element[0].nodeName
    var existingHtml = element.html();
    element.find('div').html(existingHtml + " And some added text");
}