3

In the menus.client.service.js file I'm trying to understand the structure of how the menus in the MEAN.js framework is populated

The code starts out with an empty menus object assigned to this

this.menus = {}

and then at the bottom of the file, this.addMenu('topbar') function is called

    // Add new menu object by menu id
    this.addMenu = function(menuId, isPublic, roles) {
        console.log('pre-this.menus') 
        console.log(this.menus) // empty object

        // Create the new menu
        this.menus[menuId] = {
            isPublic: isPublic || false,
            roles: roles || this.defaultRoles,
            items: [],
            shouldRender: shouldRender
        };
        console.log('post-this.menus')
        console.log(this.menus[menuId]) //complete populated menu with submenus i.e "List Articles", "New Article"

        // Return the menu object
        return this.menus[menuId];
    };

Through this one function, it seems like two other functions are called

this.addMenuItem and this.addsubMenuItem

But I don't know how it happened because I don't see them explicitly called in the file.

I think I'm missing an important concept here. I also looked at the header.client.controller.js file, but all it does is call the getMenu function and assign to $scope.menu

$scope.menu = Menus.getMenu('topbar');

Here is the full nonfunctional file code

jsfiddle: http://jsfiddle.net/4c5gc0aq/

abcf
  • 685
  • 2
  • 10
  • 25

1 Answers1

7

menus.client.service.js is just the Menus service that is injected in the modules' run blocks.

Menu items are generated (populated) from within the module configs. If you look at the articles.client.config.js for example, you will see how the menu gets populated for each module:

'use strict';

// Configuring the Articles module
angular.module('articles').run(['Menus',
    function(Menus) {
        // Add the articles dropdown item
        Menus.addMenuItem('topbar', {
            title: 'Articles',
            state: 'articles',
            type: 'dropdown'
        });

        // Add the dropdown list item
        Menus.addSubMenuItem('topbar', 'articles', {
            title: 'List Articles',
            state: 'articles.list'
        });

        // Add the dropdown create item
        Menus.addSubMenuItem('topbar', 'articles', {
            title: 'Create Articles',
            state: 'articles.create',
            roles: ['admin']
        });
    }
]);

I got this example from the 0.4.0 version, but I'm sure it's very similar in earlier versions.

In the bottom of menus.client.service.js you can also define more menus, like side-menu, or role based menus displayed for users with specific roles (like admins):

this.addMenu('top-admin', {
    isPublic: false,
    roles: ['admin']
});
this.addMenu('top-user', {
    isPublic: false,
    roles: ['user']
});

And then populate them with menu items in the respective module's config (run) block. Eg:

// Add the articles dropdown item
Menus.addMenuItem('top-admin', {
    title: 'Articles',
    state: 'articles',
    type: 'dropdown'
});

// Add the dropdown list item
Menus.addSubMenuItem('top-admin', 'articles', {
    title: 'List Articles',
    state: 'articles.list'
});
orszaczky
  • 13,301
  • 8
  • 47
  • 54
  • Perfect, totally overlooked that file. Thanks a lot! – abcf Feb 14 '15 at 16:28
  • How to change the order of menu? – Vinay Mar 10 '16 at 17:51
  • 1
    @Vinay You need to specify the order of the menu that you are adding. For example: function menuConfig(Menus) { Menus.addMenuItem('topbar', { title: 'Cuentas', state: 'accounts', type: 'dropdown', roles: ['*'], position: 1 }); } You need to use the attribute >> position. position (Optional; Default: 0) - Specify the order of appearance. – Juancarlos Rodríguez Apr 09 '16 at 06:55
  • @JuancarlosRodríguez Thank you so much. Do you use yeoman meanjs generator to scaffold you mean app? – Vinay Apr 10 '16 at 16:14
  • 1
    Welcome @Vinay Yes, that's what I'm using – Juancarlos Rodríguez Apr 13 '16 at 04:43