Forcefully disable template caching in AngularJS - angularjs

I am using AngularJS and have implemented routing using it. I want to make sure whenever route changes template is fetched from server and not obtained from cache, is there a way I can force this to happen ?

This should hopefully work:
app.run(function($rootScope, $templateCache) {
$rootScope.$on('$viewContentLoaded', function() {
$templateCache.removeAll();
});
});

According to the comment on the accepted answer, this should be the correct code:
app.run(function($rootScope, $templateCache) {
$rootScope.$on('$viewContentLoaded', function() {
if($templateCache) {
$templateCache.removeAll();
}
});
});

Related

ngRoute infinite loop when changing path on a root event

I'm not sure why, but when I catch an event from JQuery, update the route and notify Angular of the change, it goes into an infinite route. It's easy to reproduce, say you have a screen like this:
The click of the button is handled by jQuery, because the jquery library doesn't seem to work in a directive so I put it in a service. Once the controller loads I initialize this. Then when the user clicks that button, I catch this jquery event, and raise a new event on the root scope so that I know to navigate to the new view. Here's the code:
(function(angular, $) {
var app = angular.module('app', ['ngRoute']);
app.config(['$locationProvider', '$routeProvider',
function config($locationProvider, $routeProvider) {
$routeProvider.when('/', {
templateUrl: 'list.html',
controller: 'ListController'
});
// The view I am trying to reach via jquery event.
$routeProvider.when('/Edit', {
templateUrl: 'edit.html',
controller: 'ListController'
});
$locationProvider.html5Mode(true);
}]);
app.controller('ListController',
function ListController($scope, $rootScope, $location, JQuerySerivce) {
// Initialize the button click listener.
JQuerySerivce.registerBtn();
$rootScope.$on('clicked', function() {
$location.path("./Edit");
// Notify angular stuff happened.
$scope.$apply();
});
});
app.controller('EditController', function EditController() {
console.log("Edit view loaded!");
});
app.factory("JQuerySerivce", function ($rootScope){
return {
registerBtn: function() {
$('#jqueryBtn').on('click', function() {
$rootScope.$broadcast('clicked');
});
}
};
});
})(angular, jQuery);
The working plunker example:
https://embed.plnkr.co/WIwRreYtofGKQWdjTeQx/
[EDIT]
To clarify my question, how can I prevent this infinite loop from happening? All of the other quesitons I've found concerning routing and infinite loops have usually been some sort of mistake that introduces a loop. In this case I'm just navigating and the framework is dying. Maybe my approach is wrong? I'm open to changing it if anyone has an alternative. I can't escape the jquery event though :/ Any help would be much appreciated.
$location.path("/Edit");
instead of
$location.path("./Edit");
?

Redirect to a external link if state not found

I'm building an angular application where I need to redirect a user to an external link if the state is not found ('otherwise').
I'm using UI-Router.
Could not find any examples.
Any help will be appreciated!
UPDATE :
I was able to achieve redirecting to external link by passing a function to otherwise :
$urlRouterProvider.otherwise(function() {
window.location.href = 'http://www.google.com';
});
Thanks for the help and sorry for lack of clarity!
You probably want the stateNotFound event:
angular.module('myApp', ['ui.router'])
.config(function($stateProvider) {
})
.run(function($rootScope, $window) {
$rootScope.$on('$stateNotFound', function(){
// go somewhere else
$window.open('//google.com');
// or use $window.location = url here;
});
});
Live demo (click here).

Why is the alert displayed two times on button click?

Could you please tell me why alerts display two times on button click?
here is my plunker
http://plnkr.co/edit/vtmYAG2d1gmnPjnxovJw?p=preview
/*global define, console */
define(['app'], function(app){
'use strict';
app.controller('LoginCtrl', ['$scope', function($scope) {
$scope.login = function () {
alert("Login is clicked")
};
}]);
});
If you use a newer version of Ionic it works:
http://plnkr.co/edit/K2BLrUyOEeoDxHc9LyTl?p=preview
I used http://code.ionicframework.com/1.0.0/js/ionic.bundle.min.js
your example uses
http://code.ionicframework.com/1.0.0-beta.1/js/ionic.bundle.min.js
requirejs.config({
paths: {
ionic:'http://code.ionicframework.com/1.0.0/js/ionic.bundle.min',
},
shim: {
ionic : {exports : 'ionic'}
}, priority: [
'ionic'
],
deps: [
'bootstrap'
]
});
The digest cycle runs at least two times by angularjs. So, probably the reason for the alert is appearing two times is digest cycle.
But others said to change version and you would get alert calling only once. But if you don't want to change the version, there's a workaround to this:
$scope.login = function () {
alert("Login is clicked");
$scope.login = function(){
return false;
}
};
working demo
This method allows you to call function only once. It might be helpful for others who want to stop digest cycle.
Problem fixed you have used obsolete minified version of ionic and requirejs non-minified.
Just change your ionic version to --
http://code.ionicframework.com/1.0.0/js/ionic.bundle.js
and requireJs to
RequireJS 2.1.17
it's working fine ...change version in your fiddle

How do you render a view from a controller in Angular?

I want to render /list after updating the Quiz successfully. How do I do that?
this.update = function() {
Quiz.update($scope.quiz, $routeParams.id)
.success(function() {
// render /list
});
};
Well, the sanest solution would be using routing combined with $location, like this:
this.update = function() {
Quiz.update($scope.quiz, $routeParams.id)
.success(function() {
$location.path('/list');
});
};
Of course, it goes without saying that you need to inject $location into your controller, and define the /list route (I assume you already have this).
Have a look at this is you want additional functionality: https://docs.angularjs.org/api/ngRoute/directive/ngView
Are you using ngroute or ui-router?
If ngroute
$location.path('/list');
If ui-router
$state.go('stateNameForList');

How can I load jQuery before navigating to a new page with ui-router?

I have an AngularJS application that uses ui-router. It's a SPA application and I want to keep the initial load time down as much as possible. When a user clicks on a link to go to some map page on my application I need to load jQuery. Here's the ui-router config code:
var homeMap = {
name: 'home.map',
parent: 'home',
url: '/:map',
views: {
'root': {
templateUrl: '/Content/app/home/partials/home.html',
},
'content': {
templateUrl: function (stateParams) {
return '/Content/app/home/partials/' + stateParams.content + '.html';
},
}
}
};
Is there a way that I can do the loading of jQuery and confirm that it has finished before moving the user to the new page. Note that I need to do this with some kind of resolve inside the ui-router code block rather than coding any script elements in my page that I load.
In the resolve block, setup a promise and return it, load jQuery, then poll until it exists on the window object. Once it does, resolve the promise:
resolve:{
jquery: function($http, $q){
if (typeof jQuery === 'undefined') {
// load jQuery
var wait = setInterval(function() {
if (typeof jQuery === 'function') {
deferred.resolve();
clearInterval(wait);
}
}, 100);
return deferred.promise;
}
}
}
Demo
$locationChangeStart might help with what you want, there's also $routeChangeStart depending on which is more suitable for your situation.
So something like this:
$rootScope.$on('$locationChangeStart', function(event) {
//Load JQuery here
});

Resources