I use ng-view to pull in a partial to page. After that I would like to load in another partial to the page that would be right next to the initial partial that was brought in.
How would I bring in another partial from a angular controller?
Because of how ngRoute was designed, you can only have one ng-view per ng-app instance.
However, it looks like you are looking for ng-include since the routes do not seem to come into play.
Otherwise, to work around the issue of URL routing having only one template, you have two options:
Use ui-router Note: Under heavy development, may introduce breaking changes.
Define and use two angular applications which can reuse the controller/service code. However, then the two applications will not be able to share state.
Related
From what I've read, Angular doesn't support multiple views out of the box for URL changes.
What I really want is to have a set of controllers in charge of different parts of the application UI, that each respond in their own way to route changes.
Is there a common solution for this, or am I thinking about the application structure in the wrong way?
The ui-router plugin doesn't appear (to me) to solve this particular problem in the way I'd like - it's a state-first approach with optional URL changes, as opposed to URL-first.
Angular actually does support multiple views out of the box, what it doesn't support is multiple ng-view out of the box. You can use ng-include and place a controller on that element and watch for any route changes you need.
Essentially you'd do something like this:
<ng-include src='"menu.html"' ng-controller='MenuCtrl'></ng-include>
<div ng-view></div>
The ng-include's controller you would be watching for route changing and doing whatever is needed.
The ng-view of course is driven by the route changes setup in your app config.
I have a top menu in my angular app. Since the menu is static, it is not included in the ng-view.
I could leave the menu source in the index.html, but for cleaner markup I decided to pull it into a partial.
Now my question: Is it better practice to use ng-include and a separate controller or implement a custom directive instead?
I won't really reuse the code so I think ng-include would be fine but a directive somehow feels more "the angular way"...
ng-include is just fine to load partial views for your application(I assume that your index.html is kind of a master page with one ng-view section).
Each section that is loaded can have it's own controller(e.g. if you have a div with 'hot news' that fetches stuff from the db, you can just include the partial view using ng-include and let the new view have a ng-controller directive that will perform a ajax call to fetch stuff from the db).
I would add a directive only if need extra functionallity.
If you can live without it then why bother?
Is it better practice to use ng-include and a separate controller or
implement a custom directive instead?
Best practice is always subjective.
I have taken this approach:
If I want to build for reuse; I create a directive.
If I want to separate code for organizational purposes, I use an ng-include
I would seriously suggest looking at ui-router (https://github.com/angular-ui/ui-router), which gives you an enormous amount of flexibility to setup layout pages that have different sections (main, left-nav, content). It's a much more flexible means of using Angular to setup page structure so that you don't have to repeat yourself. It's also tremendously powerful by allow you precise control over different section of a page depending on where people are in your application.
The docs do a reasonably good job explaining it, but try to focus on the area which talks about multiple-named views.
ng-include will work fine, but it if you want more control, ui-router is the way to go.
There are two ways (AFAIK) to associate a controller with a view template/partial: the route specified in $routeProvider and the ngController directive. Especially (but not exclusively) for simple routing, is there any benefit/efficiency of one over the other?
My project currently uses the $routeProvider approach, but I've been given the task of nesting views. This seems simple enough with ngInclude, as long as the partial specifies its ngController.
This question really comes down to design and as such it is a bit opinion based. That in mind, the best guidance I know is:
$routeProvider - Allows you to specify a single controller for a template. Since this is part of the routing it makes it easy to find the controller that goes with the page. I use this to store and load overall page logic rather than element specific logic.
This is also important because it means you can load the exact same template for two different routes but the behavior and data could be different because the controller can be changed. This is not something that is easy to do with the ngController option.
ngController - This scopes the controller to a specific element on the page/template. That can make the code easier to read when you need multiple controllers on a single page and it allows the controller to be more specifically scoped.
So it really comes down to scope and intent. Hopefully these rules will help when deciding which to use.
If you think of a view including all scripts as a self-contained package, developed by a single person or team, then ngController is the way to go, imho.
$routeProvider on the other hand provides you with advanced features like injection of values via the resolve property of the route. That way you can have your AJAX loaded data directly injected into your controller, e.g., instead of the controller having it to get itself. Or have the route change to wait for that data etc.
Btw: If you need routing and nested views you can take a look at angular ui-router
I am a total Angular (and JS) beginner.
I want to develop something like this:
(with apologies to #PhillipKregg for borrowing his excellent illustration).
Effectively, I want nested tabbed notebooks - a row of tabs (views?), each which can contain data or another row of tabs (each of which ...).
Googling seems to return more recommendations for UI-Router, but I imagine that UI-Bootstrap's Tabs or Accordion could also be used (or even UI-Bootstrap's Pagination, with a single view whose contents I update according to the selected page?).
All else being equal, I will go with whichever is easiest for a novice to understand and implement (which is that?).
But - are there performance issues? For instance, will one download the content of all the views immediately or initial page load (thus increasing initial page download time)? Will one only download the data for a view when it becomes active (which seems preferable)?
Anything else I need to consider?
Yes, ui-router & ui-bootstrap.tabs are the best tools for the job at the moment. To do something similar would require mixing two types of ui-router config patterns, nest views & multiple named views. I'd suggest reading both these wiki pages:
https://github.com/angular-ui/ui-router/wiki/Nested-States-&-Nested-Views
https://github.com/angular-ui/ui-router/wiki/Multiple-Named-Views
Here's a basic draft demo of something similar to your illustration, using ui-router & ui-bootstrap.tabs: http://plnkr.co/edit/BUbCR8?p=preview
The easiest way to get started is to use ng-boilerplate https://github.com/ngbp/ngbp, it uses ui-router & has best-practice directory structure. It also addresses performance issues by compiling html to js & adding templates to $templateCache, thus kicking lots of XHR requests to the curb.
Regards to data downloads, data would typically be managed by a angularJS service singleton instance, separate from any views. How & when you invoke any service from any view is totally your choice. This is a pretty good tutorial on angular services: http://www.ng-newsletter.com/posts/beginner2expert-services.html
I would recommend to use angular $routeProvider for your task. This will make easy to handle code and view fragments.
With bootstrap you will need to put all the code on single page and that is less manageable. Have a look at
http://viralpatel.net/blogs/angularjs-routing-and-views-tutorial-with-example/ and
For nested views
http://www.bennadel.com/blog/2441-Nested-Views-Routing-And-Deep-Linking-With-AngularJS.htm
Also $routeProvider is better for navigation. Back Forward through view...
Angular will load views when required.(Lazy loading.) So better for performance...
Hope this will help.
I personally don't get the point of wanting to use bootstrap tabs with angular's ui-router. It is counter-intuitive. Just don't use bootstrap's tabs and set up the "sub-tabs" in the angular config. This will also make your code more readable. Only add ui-bootstrap if you NEED the extra features. An example config is below
$stateProvider.state('A', {
url: "/A",
controller: "testController",
templateUrl:'pages/A.html'
})
.state('A.B', {
url: "/A/B",
controller: "testController2",
templateUrl:'pages/A.B.html'
})
I read about angularJS routing. I want to implement it in my web app, but unfortunately I have a rather difficult situation changing to routing now I think. This is how my app works now (and I know it's probably not the way it should, but it does work):
I have one controller for the whole app.
The view is built with some divs, one of which is a menu div. The others are 'partial' views as angularjs calls them I guess. But the problem I see here is that two of my partial views can be shown at the same time (page is built like this, partial view only takes a portion of the page for itself).
So what I am doing is: I click the button on the menu -> one partial view shows up (ng-show), then I can click something on this partial view to get the second partial view opened on the same page (menu and first partial must stay the way they are).
At the moment I include partials within some divs with php include (which is I am sure the wrong way) and the divs have ng-show on them so that nothing is shown on the beginning. Then I manipulate all the clicks in the menu with setting ng-show parameters of all my partials (views). So if one button is clicked I hide all the others (with ng-click and a function inside controller). But this is tedious work and not the angularJS way and that is why I am asking this question here.
Example of my included partial (stripped of all unnecessary css classes etc):
<div ng-show="showNames">
<?php include_once("views/AREA1/names.php") ?>
</div>
And names.php has for instance just some few elements with ng-repeat and other angularJS directives… I have many includes like that and they work with just ng-show manipulation very well. But now that I grasped some of the AngularJS concepts I see that I made a mistake…
To sum up: how can I use angularJS routes (with ng-view perhaps?-not necessary) to show views within my web app? (taking into account the situation that I have described above). I just want user to be able to know on what "part of page" he is at any given moment.
EDIT: I went trough this and I reckon I could work it out: I need a structure similar to the one in this example 2.1 Online Demo, but furthermore I need to be able to click something on ng-view which should open another view (first one should stay in place). Any idea how to accomplish this?
By using routing feature in AngularJS, the html content of ng-view will be totally replaced by the new partial. You should not use ng-view for such a purpose like showing multiple partials at the same time.
But you can think about mix the ng-view and ng-include.
Let's say, we click each item on the menu, ng-view changes the sub-partial, you can have ng-include in your sub-partials which we can all it here like sub-sub-partial.
Try reading ng-include
AngularJS has ng-view which would contain the main theme of current context, rest of the UI elements are all managed by ng-include. Routes also work in sync with nv-view.
If your view requirement are complex look at ui-router component that supports various combinations.