点击菜单和不同的子菜单

时间:2014-11-14 23:00:02

标签: angularjs

我正在尝试以角度构建菜单和子菜单。 我想要做的是拥有两个对象数组 菜单

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/

如何改进我的解决方案?

4 个答案:

答案 0 :(得分:4)

不要重新发明轮子:) UI路由器是一种预先打包的解决方案,可以为您处理嵌套路由。

如果你有一个项目菜单,并且你想在选择其中一个项目时显示另一个项目菜单,那么UI路由器就是这样做的。 https://github.com/angular-ui/ui-router

答案 1 :(得分:0)

由于缺少信息,无法给出确切的答案,但是例如,如果您在应用程序的其他位置使用带有不同菜单项的指令,我建议从控制器传递菜单数组(ng -controller,而不是指令的控制器)通过指令的范围。

此外,您正在寻找指令直接通信的有效标准方式(在您的情况下,菜单和子菜单指令之间的通信以通知项目选择更改),使用指令的控制器。这是一个很好的教程。

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

答案 2 :(得分:0)

要在控制器或指令之间进行通信,您应该使用服务

从角度指南(https://docs.angularjs.org/guide/services):

  

Angular服务是使用依赖注入(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>

希望它有所帮助!

答案 3 :(得分: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