2014-11-14 3 views
3

Я пытаюсь создать меню и подменю в угловом. То, что я хочу сделать, это есть два массива объектов менюМеню и другое подменю при нажатии

menu = [{name: 'Name1', link: '/link1'}, {name: 'Name2', link: '/link2'}] 
submenu = [[{name: 'SubName1', link: '/Sublink1'}, {name: 'SubName1', link: '/sublink1'}], 
[[{name: 'SubName2', link: '/Sublink2'}, {name: 'SubName2', link: '/sublink2'}]] 

Так что, когда я нажимаю Name1 будет выбран первый массив SubMenu и при нажатии Name2 второй массив будет выбран. Как я могу создать две Директивы для главного меню, а второй для второго и иметь возможность общаться между ними по щелчку. Я попытался построить это в контроллере, я смог выбрать подменю, используя $index, но подменю нельзя перемещать, как мне нравится, потому что оно должно находиться под контроллером.

я, наконец, удалось решить мою проблему здесь решение: http://jsfiddle.net/4kjjyL4s/4/

Как я могу улучшить мое решение?

ответ

0

Не может дать точный ответ, поскольку информация отсутствует, но, например, если вы используете директивы с различными пунктами меню в других местах вашего приложения, я бы рекомендовал передать массив меню из контроллера (ng-controller, а не директивный контроллер) через область действия директивы.

Кроме того, вы ищете стандартный способ передачи директив напрямую (в вашем случае, связь между директивой меню и подменю для уведомления об изменении выбора элемента), используйте контроллер директивы. Вот хороший учебник.

https://thinkster.io/egghead/directive-to-directive-communication/

4

Не изобретайте колесо :) UI маршрутизатора является расфасованным решением, которое обрабатывает вложенную маршрутизацию для вас.

Если у вас есть меню элементов, и вы хотите отобразить другое меню элементов, когда выбран один из элементов, то маршрутизатор пользовательского интерфейса выполняет именно это. https://github.com/angular-ui/ui-router

0

Для связи между контроллерами или директивами вы должны использовать услуги.

Из угловой направляющей (https://docs.angularjs.org/guide/services):

Угловые услуги взаимозаменяемы объекты, которые соединены вместе с помощью инъекции зависимостей (DI). Вы можете использовать службы для организации и совместного использования кода в своем приложении.

Я проверил код, который вы опубликовали на jsfiddle (http://jsfiddle.net/4kjjyL4s/4/), и я старался максимально использовать его. Ниже перечислены мои изменения в файле JavaScript (пожалуйста, прочитайте комментарии в коде).

var app = angular.module("app",[]); 

app.controller('main', function(){}); 
// The service will be responsible for the shared objects and logic 
app.service('MenuService', function() { 
    var list = [ 
    { 
     name: "Menu1", link: "#menu1", 
     submenu: [ 
     { name: "Menu1Sub1", link: "#submenu1" }, 
     { name: "Menu1Sub2", link: "#submenu2" } 
     ] 
    }, 
    { 
     name: "Menu2", link: "#menu2", 
     submenu: [ 
     { name: "Menu2Sub1", link: "#submenu1" }, 
     { name: "Menu2Sub2", link: "#submenu2" } 
     ] 
    } 
    ]; 

    var selected = []; 

    // methods and attributes published under the **this** 
    // keyword will be publicly available 
    this.getMenu = function() { 
    return list; 
    }; 

    this.getSubmenu = function() { 
    return selected; 
    }; 

    this.select = function (menuItem) { 
    // this does the *trick*! 
    // if we use the assignment operator here, we would replace the 
    // reference returned in the getSubmenu() method, so as the original 
    // reference did not change, angular's dirty checking would not detect it. 
    // using angular.copy() method, we are copying the contents of the 
    // selected submenu over the same reference returned by getSubmenu() 
    angular.copy(menuItem.submenu, selected); 
    }; 
}); 

// No $rootScope injection results in better re-usability. When you were 
// relying in $rootScope sharing, both directives should live in the 
// $rootScope, so if you add them inside a ng-controller created scope 
// they would not work anymore 
app.directive("menu", function() { 
    return { 
    restrict: "E", 

    // no need to isolate scope here, *scope:true* creates a new scope 
    // which inherits from the current scope 
    scope: true, 

    // with controllerAs (introduced in angular 1.2), you can skip 
    // polluting the scope injection. 
    controllerAs: "ctrl", 
    controller: function(MenuService) { 
     this.list = MenuService.getMenu(); 
     this.changeSub = function (menuItem) { MenuService.select(menuItem); }; 
    }, 
    template: "<div ng-repeat='menu in ctrl.list'><button ng-click='ctrl.changeSub(menu)'>{{menu.name}}</button></div>" 
    }; 
}); 

app.directive("submenu", function() { 
    return { 
    restrict: "E", 
    scope: true, 
    controllerAs: "ctrl", 
    controller: function(MenuService) { 
     this.sublist = MenuService.getSubmenu(); 
    }, 
    template: "<span ng-repeat='menu in ctrl.sublist'>{{menu.name}} | </span>aa" 
    }; 
}); 

А вот обновленный HTML-файл, просто чтобы показать обе директивы теперь работать не напрямую вставляются в $rootScope

<div ng-app="app"> 
    <div ng-controller="main"> 
     <menu></menu> 
     <h1>Hello World!</h1> 
     <div class="main-content"> 
      <submenu></submenu> 
     </div> 
    </div> 
</div> 

Надеются, что это помогает!

0

Попробуйте этот код:

function MyCtrl ($scope) { 
     $scope.subMenu = []; // default is false 

    $scope.toggleSubMenu = function (index) { 
     $scope.subMenu[index] = !$scope.subMenu[index]; 
    }; 
} 

HTML

<ul> 
    <li ng-class="{active: subMenu[0]}"> <a href="#hello" ng-click="toggleSubMenu(0)">Name1</a> 
     <ul> 
      <li>test</li> 
      <li>test</li> 
      <li>test</li> 
     </ul> 
    </li> 
    <li ng-class="{active: subMenu[1]}"> <a href="#foo" ng-click="toggleSubMenu(1)">Name2</a> 
     <ul> 
      <li>bar</li> 
      <li>bar</li> 
      <li>bar</li> 
     </ul> 
    </li> 

</ul> 

Также Проверить this

Смежные вопросы