Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Durandal and MVC4 Areas for multiple SPAs

I have a internet application mvc4 with areas, for my organization each area represent a SPA and through "Manage NuGet Package" I installed "Durandal 1.2.0", "Durandal Transitions 1.2.0" and "Durandal Router 1.2.0". I organized the folders and quit the "views" and "viewmodels" from folder "App" of Durandal and put the new views in folder "VIews" of mvc4 area for example:

Areas-->NewArea-->Views-->ControllerFolder-->views-->shell.html

Then I put the '"viewmodels" in "Script" folder for example:

Scripts-->NewArea-->ControllerFolder-->viewmodels-->shell.js

Scripts-->NewArea-->ControllerFolder-->main.js

Then I changed paths for JS of durandal, for example in main.js:

define(['../../../App/durandal/app',
    '../../../App/durandal/viewLocator',
    '../../../App/durandal/system',
    '../../../App/durandal/plugins/router',
    '../../../App/services/logger'],

And I changed main.js in the next line:

viewLocator.useConvention('viewmodels', '../Areas/NewArea/Views/ControllerFolder/views');

But that configuration of folders fails because the next line calls various times the module "viewLocator" in its definition and rewrite the configuration of "useConvention" with default value:

app.setRoot('viewmodels/shell', 'entrance');

That behavior only happen when the folders "views" and "viewmodels" don't stay under "App" folder of "Durandal".

Please help me, how to have various SPAs in the same project?

like image 614
kuskunko Avatar asked Mar 18 '13 16:03

kuskunko


2 Answers

You might want to consider your deployment strategy. For example, if you need to optimize this app, both SPAs will end up in the same file. However, instead of having them both under the app folder, you can make separate folders, and give each SPA it's own main.js file.

In more advanced scenarios, you may create a "bootstrapper" app that loads one or another of the SPAs. The bootstrapper would contain code that is common to both SPAs. But each SPA (and the bootstrapper) can be optimized independently.

There are many options. Mainly, consider your final deployment strategy and that will help guide you here.

Also, the issue you have above is probably related to the fact that the standard conventions may not work in your setup, and you would need to override some functions with your own mapping.

like image 68
EisenbergEffect Avatar answered Sep 19 '22 19:09

EisenbergEffect


I ran into the exact same problem this morning. I originally formatted the project to be:

  • app/spa1/viewmodels
  • app/spa1/views
  • app/spa2/viewmodels
  • app/spa2/views

Using this structure I hit the exact same wall you did. After reading your post, I restructured the project to be:

  • app/viewmodels/spa1
  • app/viewmodels/spa2
  • app/views/spa1
  • app/views/spa2

Using this structure, navigation works fine. I set up three SPAS and was able to navigate all three. The other benefit of this structure is that you are now following the standard convention so you don't have to configure the view locator. Just make sure the main.js file for each spa uses:

  • app.setRoot('view models/spa1/shell), app.setRoot('view models/spa2/shell), etc.

Finally, by structuring this way, you move the main.js files up the structure which eliminates the ../../../ in all your defines.

I hope this helps.

like image 28
Woods Avatar answered Sep 19 '22 19:09

Woods