2013-09-12 6 views
0

Я пытаюсь создать директиву для ящиков, которые могут быть использованы в моем приложении. Что я хочу сделать, так это: когда пользователь открывает один ящик, мне нужны другие открытые ящики для закрытия.Возможно ли получить доступ к экземплярам директивы внутри определения директивы?

Это мой текущий код:

Markup

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

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

Возможно ли открыть один ящик, чтобы остальные ящики закрылись, используя только директиву?

ответ

0

Я бы скомбинировал директиву с услугой ящика. Используйте службу ящика, чтобы разоблачить все, что необходимо для координации между различными моделями, представлениями и т. Д. Например, вы можете настроить каждую директиву ящика на службу (например, отправить обратный вызов для уведомления). Тогда у вас может быть метод службы, который при вызове отправит сообщение всем зарегистрированным ящикам для закрытия. Это также делает его более чистым для реализации, потому что, если что-либо еще должно взаимодействовать с ящиками, они могут взаимодействовать с сервисом вместо директивы и оставаться отделенными от реализации пользовательского интерфейса.

+0

Как я могу получить конкретный экземпляр ящика и подачи его на службу тогда? Могу ли я добавить методы open() и close() в экземпляр ящика, чтобы они могли быть закрыты из службы? – Loupax

0

Вы можете использовать контроллер, общий для всех экземпляров директивы.

От AngularJS documentation on directives:

* контроллер - контроллер функции конструктора. Контроллер создается до фазы предварительной привязки и делится с другими директивами (см. Атрибут require). Это позволяет директивам общаться друг с другом и дополнять поведение друг друга.

Вы можете обратиться к директиве Аккордеона, которая является частью проекта AngularUI Bootstrap here.

0

Примечание

Даже если я получил ответы на некоторые вопросы, которые указывали мне на хорошем направлении, реализующие эти предложения потребовалось некоторое дополнительное домашнее задание. Я представляю свои результаты здесь, пока текущая реализация.

Используя предложение Jeremy Likness's, я создал сервис, в котором хранились записи всех ящиков. Проблема, которую я придумал, - «, если не DOM, что is ящик?». После некоторого чтения выяснилось, что я могу создать конкретную область для каждого ящика, используя опцию 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); 
     });   

    } 
}; 

}); 
Смежные вопросы