Tom
Tom

Reputation: 406

AngularJS app architecture/structure

I am developing an application with the following structure:

|--------------------- header -------------------|
|                                                |
|-----sidebar-----|-----------Main View----------|
|                 |                              |
|   constraints   |       list of topics         |
|                 |                              |
|                 |                              |
|                 |                              |
|_________________________________________________

enter image description here

Constraint selections are made in the sidebar which effect the list of topics are shown in the Main View Area.

Now this all works fine however i have come to the stage where my app is becoming more complex.

In certain cases I want to replace what is in the Main View completely and not show a list of topics but show the topic itself (render another template e.g views/topic.html) but i still want to keep the sidebar and not reload it. And then be able to return back to the list of topics.

This new topic view within Main View will also need to use a another controller as-well as the controller for the sidebar which is currently 'resultsController'.

Currently i use ng-route and the following structure:

$routeProvider.when('/', { templateUrl: 'views/results.html' });

<ng-view></ng-view>

// views/results.html
//------------------------------------------------------
<div data-ng-controller="resultsController">
   <div ng-include src="'views/header.html'"></div>
   <div ng-include src="'views/sidebar.html'"></div>
   <div id="Main View">
         <div ng-repeat="topic in topics"></div>
    </div>
</div>

What would be the correct way to structure/architect my app?

(i have looked ui-router would this be the way to go? if so how would i structure my routes/view/controllers?)

Upvotes: 0

Views: 344

Answers (1)

Chris T
Chris T

Reputation: 8216

UI-Router can handle this in two ways, nested views and named views:

Nested Views:

http://plnkr.co/edit/ngpVmjsxRaCmLYx3wbA5?p=preview

In this example, the views nest, starting from top, with side nested in top, then list and item nested in side.

$stateProvider.state('top', {
  url: "",
  templateUrl: "header.html",
  controller: 'topCtrl'
})
.state('top.side', {
  url: '/app',
  templateUrl: "side.html",
  controller: 'filterCtrl'
})
.state('top.side.list', {
  url: "/items?query",
  templateUrl: "items.html",
  controller: 'listCtrl'
})
.state('top.side.item', {
  url: "/:id",
  templateUrl: "item.html",
  controller: 'itemCtrl'
});

Named Views:

Another way is to define named placeholders for the views, then plug them in with view definitions on the state states. These are called "multiple named views". http://plnkr.co/edit/lz00GAXowMGTAba3dc8a?p=preview

The placeholders are named ui-views:

<body ng-app="nested">
  <div id="header" ui-view="header"></div>
  <div id="side" ui-view="side"></div>
  <div id="content" ui-view="content"></div>
</body>

Those placeholders get filled in with views from the state definitions:

.state('top', {
  url: "",
  views: {
    header: { templateUrl: "header.html" },
  }
})
.state('top.list', {
  url: "/items?query",
  views: {
    "side@": { templateUrl: "side.html", controller: 'filterCtrl' },
    "content@": { templateUrl: "items.html", controller: 'listCtrl' }    
  }
})
.state('top.item', {
  url: "/:id",
  views: {
    "side@": { templateUrl: "side.html", controller: 'filterCtrl' },
    "content@": {  templateUrl: "item.html", controller: 'itemCtrl' }
  }
});

The "side@" naming convention means plug into the ui-view named "side" which exists at the "" (root/empty string) state. This is used so you can define additional named subviews inside your other templates, then plug into those named ui-views using something like "[email protected]".

Upvotes: 1

Related Questions