0

我正在尝试为可在我的应用程序中使用的抽屉创建一个指令。我想做的是:当用户打开一个抽屉时,我需要关闭任何其他当前打开的抽屉。

这是我当前的代码:

标记

<a href="javascript:;" id="my_switch">
    Click me to toggle the drawer!
</a>
<drawer data-switch="#my_switch">
    Content of the first drawer
</drawer>

<a href="javascript:;" id="my_other_switch">
    Click me to toggle the other drawer!
</a>
<drawer>
    Content of the second drawer
</drawer>

抽屉.html

<div class="drawer_container">
    <div class="drawer" ng-transclude>

    </div>
</div>

指示

MyApp.directive('drawer', function(DrawerService){
return {        
    restrict: 'AE',
    replace: true,
    transclude: true,
    templateUrl: 'drawer.html',                     
    link: function(scope, element, attributes){         
            var drawer_switch = $(attributes.switch);
            var drawer = $(element).find('.drawer');

            var toggle = function(event){
                drawer.toggle();
            };

            drawer_switch.bind('click', toggle);
        }
    };
}); 

仅使用指令打开一个抽屉是否可能导致其余抽屉关闭?

4

3 回答 3

0

您可以使用在指令的所有实例之间共享的控制器。

来自关于指令的 AngularJS文档:

*controller - 控制器构造函数。控制器在预链接阶段之前被实例化,并与其他指令共享(参见 require 属性)。这允许指令相互通信并增强彼此的行为。

您可以在此处参考作为 AngularUI Bootstrap 项目一部分的 Accordion 指令作为示例。

于 2013-09-12T12:56:59.460 回答
0

笔记

尽管我得到了一些为我指明了方向的答案,但实施这些建议还是需要做一些额外的功课。我在这里展示我的发现,只要当前的实现。

根据Jeremy Likness 的建议,我创建了一个记录所有抽屉的服务。我提出的问题是“如果不是 DOM,那么抽屉什么? ”。经过一番阅读,我发现我可以使用scope: true指令定义上的选项为每个抽屉创建一个特定的范围,因此每个范围实例都引用它对应的抽屉。

抽屉.html

<div class="drawer_container">
    //Whether the drawer is visible is now being derermined here   
    <div class="drawer" ng-show="is_open" ng-transclude>

    </div>
</div>

服务

MyApp.factory('DrawerService', function() {
var drawers = [];
var drawerService = {
    // Adds the scope of a drawer to the drawers array. This method should be called when 
    // a new drawer gets created in order to be handled later
    addDrawer: function(drawer){
        drawers.push(drawer);       
    },
    // Closes all the drawers that are open, except for the one that is provided
    closeTheRest: function(drawer){         
        for(var i = 0; i < drawers.length; i++)
        {
            if(drawers[i] !== drawer)
            {       
                  drawers[i].$emit('forcedClose');
            }
        }        
    }
};

  return drawerService;
});

指示

MyApp.directive('drawer', function($timeout, DrawerService){
return {        
    restrict: 'AE',
    replace: true,
    transclude: true,       
    scope: true,
    templateUrl: 'drawer.html',               
    controller: function($scope)
    {
        $scope.is_open = false;
    },
    link: function(scope, element, attributes){                     
        var drawer_switch = $(attributes.switch);           
        var drawer = $(element).find('.drawer');

        DrawerService.addDrawer(scope);

        drawer_curtain.css({
        'height': $(document).height()
        });         

        scope.$on('forcedClose', function(){
            scope.is_open = false;
        });


        drawer_switch.bind('click', function(){
            scope.is_open = !scope.is_open;                 
            DrawerService.closeTheRest(scope);
        });         

    }
};  

});
于 2013-09-13T08:20:15.373 回答
0

我会将指令与抽屉服务结合起来。使用抽屉服务来公开协调各种模型、视图等所需的内容。例如,您可以让每个抽屉指令将自己注册到服务(例如,发送回调以获取通知)。然后,您可以在服务上拥有一个方法,该方法在调用时将向所有已注册的抽屉发送消息以关闭。这也使得实现更简洁,因为如果有其他东西必须与抽屉交互,它们可以与服务交互而不是指令交互,并与 UI 实现保持分离。

于 2013-09-12T12:51:15.573 回答