Preload ng-view for smoother navigation - angularjs

I'm using $location.path() to load new view inside my angular web site.
My page looks like :
<html>
<head>
</head>
<body>
<div data-ng-view="" ></div>
</body>
</html>
And I change the ng-view depending on the demands (index, home, login, etc).
Some times the navigation seems slow (some glitch stay within the page while 0.1 secs) is there a way to make the navigation instant ?
Also, I tried the ng-animate which improved that feeling but not completely.
I guess that preloading my 'views' will be one solution ..
Edit :
Feeling improved by adding :
myApp.run(function ($templateCache, $http) {
$http.get('Template1.html', { cache: $templateCache });
});

You can use a far superior library for managing states and views such as Angular UI Router.
It has support for pre-loading each resource that is needed in your nested state before rendering it (via the resolve property), in order to avoid flickering of the interface, but you can also load each resource you want individually after you have rendered your view. If you don't want to refactor your app to use ui-router (which imo makes every app far more manageable), then you'd be stuck with using $templateCache and managing the resources of your views manually.
A trick you can try to do is have your view's controller load the resources it needs after having been rendered. Also, maybe you have repeating parts of your app view wise, try to extract them in separate templates and reuse them if you can. If you can split your app in such a way that it doesn't re-render everything every time you change view, it would probably have beneficial effect on rendering speed.

Thanks to Baba. But I found a solution which does not involve to change my route (and use another library such as Angular UI Router (which is by the way super!))
My solution : preload my templates with the $templateCache and add animation (nice tuto : http://scotch.io/tutorials/javascript/animating-angularjs-apps-ngview + http://daneden.github.io/animate.css/)

Related

Using Angular's $location service to display a specific view based on current path

fairly new to Angular and have looked around this site fairly extensively, but most of the $location related threads I've found have to do with authentication and routing.
My question is: what is the best method for 1) setting up a watch on the current $location.path(), and 2) updating the view via a custom directive based on the current path?
I am currently using the ngView directive to update the majority of the page (routing works fine - no changes needed here). I now want to create a 'custom nav widget directive' that updates based on the current path, but doesn't need to go in my ngView templates (seems like a lot of repetitive code). To be clear - don't have any code written yet for the custom nav functionality. I am more looking for some guidance on best way to accomplish this and a rough outline on how.
<body>
<div ng-view></div>
<div custom-nav-widget-directive></div
</body>
I get that you want an answer that focuses on your suggested approach. But you might want to take a look at UI-Router. A powerful third-party alternative to the standard ngRouter.
UI-Router allows for Multiple Named views. You could have something like:
<body>
<div ui-view>
<div ui-view='nav'>
</body>
Where everything under div[ui-view='nav'] can change independently from the rest of your page/app which would in turn render under div[ui-view]. This would keep your nav logic and template(s) apart from those of the rest of the app/page.
Once I got to know it, UI-Router made me decrease my need for directives. Each router state and its views need their own configuration object like normal routes-- or directives for that matter--, with a controller, template, etc... Pretty cool.
If you decide to give a try do let me know, I'd be glad to help kickstart the learning curve.

How to bypass routing in Angular UI Router

I'm creating a web application in which the bulk of the functionality is deployed as an AngularJS single-page application, but there are also a few static content pages that are served in the traditional way.
Navigation within the SPA employs Angular UI Router and seems to be working correctly, as does the serving of the static pages.
However, the code architecture is such that all scripts are referenced from within the main site template and are thus served with every page, including the static pages. This is a deliberate decision, as there are some scripted features that need to accessible from everywhere, even from within the static pages.
For example, the header region of every page contains a search box with typeahead, that allows users to navigate to a view within the SPA, populated to reflect the selected content.
If a search is invoked from within the SPA, everything works as expected, and the routing mechanism correctly executes the required state transition to render the selected content. However, if the same search is conducted from within one of the static pages, although UI Router correctly processes the state transition, the content is not rendered because the static page does not contain the <ui-view> element that is usually targeted by rendering.
Although I can see what's causing the problem, I'm not sure how best to resolve it. From a novice perspective, it seems that I need to intercept the content search/selection process and execute different logic, depending on whether or not the search was invoked from within the SPA or a static page. I anticipate something like this:
if ($state.current.name) {
// The search was invoked from within the SPA, so only a state change is required.
$state.go("render", { key: selected_key });
} else {
// The search was invoked from a static page, so an SPA page load is required
What can we do here to bypass routing and issue a
server request for the corresponding SPA deep-linked page?
}
But I'm willing to guess that there is a more elegant way of dealing with this issue, maybe one that's baked into Angular UI Router.
Any suggestions please?
Many thanks,
Tim
For anyone facing a similar problem, the solution is actually very simple.
Instead of attempting to intercept and coerce the state transition, the desired behavior can be achieved through a simple modification to the main page template, enabling all pages, including static pages, to participate in Angular view rendering.
In my original implementation only the SPA page used the <ui-view> element, which resulted in the static pages ignoring the rendering that typically occurs during a state transition.
To solve the problem, I eliminated the <ui-view> element from the SPA page and, instead, added a ui-view attribute to the containing element in the main page template:
<html ng-app="myApp">
<head>
... page head content goes here ...
</head>
<body ng-controller="myController">
<div ui-view>
... server-generated page content is injected here ...
</div>
... page scripts are referenced here ...
</body>
</html>
With this change in place, every page is now effectively an SPA and capable of re-rendering to reflect state transitions (albeit that most of the time this never occurs, since the user simply views the pre-rendered content that was delivered by the server).

AngularJS - Multiple controllers watching route changes

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.

Loading in additional partials with angularjs

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.

Using angular and backbone in the same app

I am working on a backbone app that we want to migrate over to angular. However, a true "port" or "rewrite" is not an option due to resource constraints. Instead, we want to introduce angular into the app in a modular sort of way -- ie, identify and carve off easily separatable functionality and make it angular, as well as introduce any new modules (i.e. an admin module) as angular code.
Is this possible? If so: a) Where would you put your "ng-view" tag? Inside the div that you currently render your backbone-based markup? b) How do you introduce angular-routes into all of this?
You can add target="_self" for all the backbone links, then angular would not route those links. We had the same problem and adding this fixed the problem. Hope this helps..
Test
You can use angular in any place you want in your app and use it with backbone if you want but stay in mind that you're using two frameworks and in this case it's totally unnecessary and wrong, but i think that you don't have choice, all you have todo is put the directive "ng-app" where you want to use angular, here is my example:
<html ng-app="myModule">
//your code here
</html>
and the script(like any other angularjs app):
var app = angular.module('myModule', []);
// the rest of the code
I never tested before angularjs + backbone, but i think you can have some problems like to deal with data from server, who will gonna do that? Angular or Backbone?

Resources