When a webpage loads for the first time, controller of my directive needs to know what is the currently selected route.
After first load I can detect change using
$scope.$on('$routeChangeSuccess', function(){});
EDIT:
Answers below are valid but it didn't work for me because:
- I am new to AngularJS technology i didn't realize that, on our project, we are using custom route provider
- You need to inject 'ngRoute' in your module before you can use $route
You can use the $routeChangeSuccess callback signature
function(event, currentRoute, previousRoute) {}
PLUNKER
e.g.
$rootScope.$on('$routeChangeSuccess', function(event, current, previous) {
console.log(current.$$route); // displays current $route object
});
The current documentation does not show the callback signatures(IDK why) but you can see them on their github, see this line.
you need to inject $route dependency in your controller and then get the current route using $route.current
Plunker Example
Controller code snippet:
.controller('MainController', function($scope, $route, $routeParams, $location) {
//Here setting scope with $route object
$scope.$route = $route;
$scope.$location = $location;
$scope.$routeParams = $routeParams;
})
Related
I've seen some jQuery plugins for this, but I was wondering if anybody did a service or a directive that does this. Google isn't helping.
Basically, what I'd like is for the URL to update every time I go over an element with (say, a directive and) an id so that if I go to another part of the application and click back I'm returned to the header that I was reading.
Use $anchorScroll and $location
These too services should give you the desired result.
The $location service allows you to change and get the # in the url
Where as the $anchorScroll lets you pin point places in the DOC.
here is a plunker demo
And here is the main controller
angular.module('anchorScrollExample', [])
.controller('ScrollController', ['$scope', '$location', '$anchorScroll',
function ($scope, $location, $anchorScroll) {
$scope.gotoBottom = function() {
// set the location.hash to the id of
// the element you wish to scroll to.
$location.hash('bottom');
// call $anchorScroll()
$anchorScroll();
};
}]);
})(window.angular);
Best of luck
An AngularJS app was successfully including a service (called auth) in one controller (called secure) and then allowing a view handled by the secure controller to interact with the auth service using the auth.methodname() syntax.
The app uses version 1.4.8 of AngularJS, and compiled properly with the $cookies.get('keyname') syntax every time until I tried to inject auth into a second controller (called navigation) and call one of its methods from a view handled by the second (navigation) controller.
All of the sudden, the app would not compile, and the FireFox developer tools console said that $cookies.get is not a valid method. Then after I changed the syntax to $cookies[''] (despite the fact that the app is still uses version 1.4.8 of AngularJS, the $cookies.get error went away, and a new error stating that $interval is not a valid function appeared to block compilation. All the compilation errors point to the auth module, whose code has not changed since before the error appeared. I am wondering if the problem is in the way that the auth service is being injected into the navigation controller. What specific changes need to be made to the code below so that the auth service can successfully be re-used by both the navigation controller and the secure controller?
Here is the relevant part of the auth service, which has not changed (except for changing $cookies.get('') to $cookies['']) since before the new problem emerged:
angular
.module('auth', ['ngCookies'])
.service('auth', ['$rootScope', '$http', '$cookies', '$interval', function($rootScope, $http, $location, $cookies, $interval) {
var $this = this;
this.authenticated1 = $cookies['AUTH1'];
//// other stuff
$interval(function(){
//stuff
}
}
Here is the navigation controller, which might have incorrectly injected auth, and thus possibly caused the problem:
angular
.module('navigation', ['auth', 'ngRoute'])
.controller('navigation', function($scope, auth, $route) {
$scope.auth = auth;
// other stuff
}
Here is the secure controller, which worked properly before the changes, and which has not changed since before the error appeared:
angular
.module('secure', ['auth'])
.controller('secure', function($scope, auth, $routeParams) {
$scope.auth = auth;
// other stuff
}
The calling code from someview handled by navigation controller did change to include a call to auth.logout() as part of the changes before the problem appeared. Here is the someview code:
<div ng-controller="navigation" class="container">
<ul class="nav nav-pills" role="tablist" >
<li ng-class="{active:tab('home')}">Home</li>
<li ng-class="{active:tab()}"><a ng-href='auth.logout()' ng-click='auth.logout()' >logout</a></li>
</ul>
</div>
The calling code from someotherview handled by secure controller did not change since before the problem appeared, but the unchanged code is:
<div ng-show="auth.authenticated1!='yes'">
Show something in particular specified here.
</div>
This should solve the problem:
angular
.module('auth', ['ngCookies'])
.service('auth', ['$rootScope', '$http', '$location', '$cookies', '$interval', function($rootScope, $http, $location, $cookies, $interval) {
You missed the $location declaration that you 're using in the function parameters. If you're using the array notation for the parameter injection, your function parameters must match.
I have this controller attached to a div:
.controller('ShowInverterConnectController', ['$scope', '$location', function($scope, $location) {
....
}])
I would like to use the $location argument of it.
I am currently doing this:
angular.element('.ng-scope').scope().$apply(function() {
console.log('test:', angular.element('.ng-scope').scope().$location);
});
But $location is coming out undefined, is there anyway to use $location?
Thanks
Not sure what you are trying to do with Angular service outside of the app, but I assume you have a good reason, because in many cases this will be considered bad practice. Anyway.
$location is not a property of the scope, so you can't get it like you are trying. However you can use $injector service to retrieve other services like $location:
angular.element('.ng-scope').scope().$apply(function() {
console.log('test:', angular.element('.ng-scope').injector().get('$location'));
});
I was wondering if there is a way to expand my angular controller on the fly according to the user's permissions.
For example lets say that we have three different permission levels respectively (Admin,Supervisor,User) and an angular controller
app.controller("myController", ["$scope", function($scope){
$scope.userFunc = function(){....};
$scope.supervisorFunc = function(){....};
$scope.adminFunc = function(){....};
}]);
I would like to add the supervisorFunc and the adminFunc only if the user possest the right permission.
User controller will contain only userFunc
Supervisor will contain userFunc and supervisorFunc
Admin will contain all the methods (userFunc,supervisorFun and adminFunc)
Now I would like to add a separate js file that will inject the additional methods into the controller, so if you are a Supervisor your client will receive two js files, one is the main myController and an additional Supervisor Injector that will expand myController.
One important thing is that I don't want to dynamically generate myController js file at server side because it's bad practices.
any ideas ?
I like the idea, and we do the same thing (sort of).
IF the second set of controller items does not have new requirements (directives and such), you should be able to do this:
in app.js:
var app = angular.module('myModule', ["whatever-directive", "some-service"]);
app.config(['$httpProvider', '$locationProvider', function ($httpProvider, $locationProvider) {
..
..
}]);
..
..
in controllers.js
function someCtrl($scope, $location, $http) {...}
function someOtherCtrl($scope, $location, $http) {...}
in onlyForYouControllers.js - that is only added if needed
function someCtrlOnlyForYou($scope, $location, $http) {...}
Like I wrote - you must declare what ever needed in the app to start with - even if it not used by a particular set of controllers.
I want to reload a template and the connected Controller without using $routeProvider, because
my Path-structure doesn't fit with .when(...). I want to use $location.path() to read the URL and set the desired action.
But: if the path of the URL changes, the template doesn't automatically update and neither is the controller reloaded.
Is there a way to say something like this?
angular.module('myApp').controller('ctrl').reload()
I would suggest looking into the Angular UI Router written by the same guys who wrote angular. It will let you transition to different states which is what it sounds like you are trying to do.
https://github.com/angular-ui/ui-router
My solution: don't use Routes! Simply update a variable for your template, controllers don't need updates (simply update the data):
angular.module('myApp',[])
.run(['$rootScope', '$location', 'myService', function ($rootScope, $location, myService) {
$rootScope.view = "";
// Some function to read the URL
$rootScope.setRouting = function(){
var p = $location.path().split("/");
// Do things with p[0], p[1], ...
// e.g. if url is /post/123
$rootScope.view = p[0];
myService.setData(p[1]);
}
// Monitor Location changes:
$rootScope.$on('$locationChangeSuccess', function(event) {
$rootScope.setRouting();
});
// And this is useful for calling within template: ng-click="go('...')"
$rootScope.go = function(path){
$location.path(path);
}
}]);
And for the HTML:
<body>
<ng-include src="view + '.html'"></ng-include>
</body>