2015-03-25 2 views
0

Я начал разрабатывать модуль гамбургер, состоящий в основном в 2-х частей:Элегантный меню гамбургер директива

  • кнопка «Бургер-нож», который открывает меню, скорее всего, директива атрибут включая слушателя событий нажмите , dom и css agnostic
  • Элемент «burger menu», скорее всего, это директива, использующая переход, позволяющая клиенту решить, что меню содержит для повторного использования. В основном это кнопка закрытия вверху, перед элементом ng-transclude.

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

Дело в том, что у меня есть ограничение, заключающееся в том, что кнопка и меню не должны содержаться внутри друг друга. Например, один должен быть в состоянии использовать модуль как так

<ul burger-menu> 
    <li>Save</li> 
    <li>Load</li> 
</ul> 
<section id="container"> 
    <a href="" burger-opener class="burgerOpen"><a> 
</section> 

Это ограничение, как представляется, с автоматическим исключением директивы к директиве связи с использованием «требуют» синтаксис, поскольку это angularjs функциональность предполагает директивы самодостаточны. Поэтому, если я не создаю контроллер DOM верхнего уровня, содержащий мои 2 элемента ... Я застрял.

Я использую метод грубой силы, то есть использовать трансляцию от корневища для кнопки отправки «открытого» сообщения в директиву меню. Он работает как шарм, но я не удовлетворен этим.

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

Знаете ли вы? Я предполагаю, что в основном я спрашиваю, как на самом деле работают такие компоненты, как ui bootstrap modal service.

+0

Я думаю, что самый простой и элегантный способ добиться того, что я хочу, - это иметь 2 элемента под контролем burgerController и предоставить им унаследованные области. –

ответ

1

Вот что я подошел. Это кажется мне быстрым и многократно используемым, дайте мне знать, если вы можете создать что-то лучше!

В принципе, директива burgerMenu использует свою родительскую область (scope:false или ничего, она по умолчанию ложна) и устанавливает api внутри нее, используя синтаксис «контроллер как». Таким образом, кнопка, роль которой заключается в открытии меню, имеет ясный обработчик кликов с burgerCtrl.openBurger().

Вот директива burgerMenu:

angular.module('app') 
.directive("burgerMenu", [function() { 
    return { 
     scope: false, 
     controller: function() { 
      var self = this; 
      this.openBurger = function() { 
       self.isOpen = true; 
      }; 
      this.closeBurger = function() { 
       self.isOpen = false; 
      }; 
      this.isOpen = false; 
     }, 
     controllerAs: 'burgerCtrl', 
     restrict: 'E', 
     replace: true, 
     transclude: true, 
     templateUrl: 'js/app/burgerMenu/_burger.tpl.html' 
    } 
} 
]); 

Шаблон:

<section class="nav_bar" ng-class="{open:burgerCtrl.isOpen}"> 
    <div class="nav_content" ng-show="burgerCtrl.isOpen"> 
     <h1 ng-click="burgerCtrl.closeBurger();">X</h1> 
     <ng-transclude></ng-transclude> 
    </div> 
</section> 

Css (основная идея):

.nav_bar { position:fixed; } 
.nav_bar.open { width: 240px; } 

Использование:

<section id="header"> 
    <div class="burger" ng-click="burgerCtrl.openBurger()"></div> 
    <h1>App title</h1> 
</section> 
<section data-burger-menu> 
    <ul id="menu"> 
     <li><a href="#/" ng-click="home.save();">Save</a></li> 
     <li><a href="#">Share</a></li> 
     <li><a href="#/load/1">Load n°1</a></li> 
    </ul> 
</section> 
Смежные вопросы