Question

I'm working on an app that will require different views depending on the user role. Initially, I managed to separate my interaction with the API using a separate folder that contains the ajax request operations and models in order to avoid repeated code inside the VMs.

  • app/controllers/ - contains GET, POST, PUT, DELETE operations and models for each object

And then I have the structure for the rest of the application:

app/building/ [route:building/]
  - shell.html
  - shell.js
  - /offices (list of offices)
    - index.html
    - index.js
  - /equipment (list of equipments)
    - index.html
    - index.js

app/offices/ [route:offices/:id]
  - shell.html
  - shell.js
- /employees (list of employees)
  - index.html
  - index.js
- /details (office details)
  - index.html
  - index.js

app/employees/ [route:employees/:id]
  - shell.html
  - shell.js
  - /report (individual employee data)
    - index.html
    - index.js
  - /details (empoyee details)
    - index.html
    - index.js

This will be admin role. As you can see, a lot of shells, sub-shells, child routers and routes. And changes will need to be made because not all roles will have access to the same routes.

At first, I tried the viewURL approach, where I save the role at the beggining of the session and just serve the appropriate view using viewUrl, but then I noticed that the files were getting too bloated:

  • had to make changes to the main router and child router and remove declared routes for lower level users
  • separate views for each page (admin.html, employee.html) all sharing the same view model that contains functions that will never be used by the employee

Then I came up with another structure. It's the same as before, except each role will have their own folders:

app/roles/admin/
  - building/
    - ...
  - offices/
    - ...
  - employees/
    - ...
app/roles/employee
  - building/
    - ...
  - offices/
    - ...
  - employees/
    - ...

When the app loads I just set the root according to the role and it's done.

Advantages

  • easier to maintain individually
  • no role check beyond app start
  • role specific code, no risk of messing something up for other roles

Disadvantages

  • more files
  • harder to maintain as a group. For example, if I rewrite a function that is shared amongst all roles, I have to replace that code for each role

I feel more confortable with the second structure, but I wanted to know what you guys thought. Or if you have a better way of handling roles.

Was it helpful?

Solution

There are lots of different ways you could approach this (e.g. customising the viewLocator.convertModuleIdToViewId method comes to mind), but I think what you've got is OK provided you're not repeating too much code between the "same" view/viewModel for each different role.

The only thing I don't like about it is that you'll end up with "hundreds" of files named "index.js" and "index.html" which makes it hard to find if you're using R#.

In order to get around the "harder to maintain as a group" problem, you could fairly easily refactor common code out into an "All" role, and then require it in for specific roles. So something like:

app/roles/all/
  - building/
    - buildingCore.js
  - offices/
    - officesCore.js

Then for buildingCore.js (obviously I'm just making up the methods up here):

define([], function() {
    var someCommonBuildingFunction = function() {
        // whatever
    }

    return {
        doSomething: someCommonBuildingFunction
    }
});

And then in (say) admin/building/building.js:

define([
    "roles/all/buildingCore"
],

function(buildingCore) {
    var viewModel = {
        activate: function() {
            buildingCore.doSomething()
        }
    }

    return viewModel;
});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top