I have a mini app with a controller that looks like that:
app.controller("MyController", [ '$scope', '$attrs', 'ServiceA', 'ServiceB', function($scope, $attrs, svc1, svc2) {
...
}])
When I tried to add angular-routing to my app, I added the following route.js file:
app.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/', {
templateUrl: 'partials/main.html',
controller: 'MyController',
controllerAs: 'appCtrl',
resolve: {
attrs: $attrs
}
})
}
]);
It seems that I can't inject $attrs like before. I've tried playing with resolve inside when() but it didn't seem to help.
I must say it looks a bit weird to inject $attrs into the controller anyway, and since that's my first app I think I'm doing something wrong here.. I need $attrs to read a data attribute from the div and initialize some array according to it. Any ideas to how I should do it or why I couldn't do it with my approach? (which worked without the routes)
Thanks!
Related
So I'm trying to learn how to use Angulars routing, following tutorials online, and I can't seem to figure out where I'm going wrong. I have the following code:
var app = angular.module('gamersplane', ['controllers', 'ngCookies', 'ngRoute']);
app.config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/pms/:box?', {
controller: 'pmList'
}).when('/pms', {
controller: 'pmList'
}).otherwise({
controller: 'pmList'
});
}])
var controllers = angular.module('controllers', []);
controllers.controller('pmList', function ($scope, $cookies, $http, $routeParams) {
console.log($routeParams);
});
However, no matter what I do, the controller doesn't get hit. I have otherwise in the router, so isn't that where it should hit if all else fails?
Yes it will hit otherwise but you can only define the redirect path into it and that redirect path will tell the url and the controller to set for the $route.current :-
redirectTo: '/pms'
Doc
You need to add a template to each route:
app.config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/pms/:box?', {
controller: 'pmList',
template: 'test.html'
}).when('/pms', {
controller: 'pmList',
template: 'test.html'
}).otherwise({
controller: 'pmList',
template: 'test.html'
});
}])
squiroids suggestion regarding otherwise was correct, you won't see a change in your test application though.
Routing is meant to be used to navigate between regions of your application. You could have an app with two routes: pms which shows a list of PMs and pms/:box zu view a particular PM Box. The main task for ngRoute is to replace a placeholder in your application (ng-view) with a given template. Without using a template on the individual routes, your $routeProvider will not navigate as expected.
Given you have two views for the regions (pmBox.html and pmList.html), you could configure your $routeProvider zu setup routing like this: https://gist.github.com/kpko/bd0231ccefbaf8c415c7
I'm pretty new to AngularJS,- in my AngularJS app I have a check in my AppCtrl controller if we have to redirect or not.
.controller('AppCtrl', function($scope, $location) {
if(window.localStorage.getItem("lastStation")) {
$location.path('/app/player/'+window.localStorage.getItem("lastStation"));
}
....
.controller('PlayerCtrl', function($scope, $stateParams) {
alert($stateParams); // This one is alerted TWICE if the $location.path is called in the AppCtrl controller
Hope someone can help with that! ;)
You must have configured routing for your application, like:
yourApp.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/app/player/:lastLocation', {
templateUrl: 'path_to_your_view',
controller: 'PlayerCtrl'
}).
.....
}]);
Now I got it ;)
.run(function($rootScope, $location) {
if(window.localStorage.getItem("lastStation")) {
$location.path('/app/player/'+window.localStorage.getItem("lastStation"));
}
});
I had to make the check in a .run method.
I am trying to create an Angular Dynamic Routing. My routing is like this:
angular.module('myApp', ['myApp.filters', 'myApp.services', 'myApp.directives']).
config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/', { templateUrl: 'partials/blank.html' });
$routeProvider.when('/:name', { templateUrl: 'partials/blank.html', controller: PagesController });
$routeProvider.otherwise({redirectTo: '/'});
}]);
Here I am using $http to get a template file inside a controller and compile it to a div id like this:
function PagesController($scope, $http, $route, $routeParams, $compile) {
$route.current.templateUrl = 'partials/' + $routeParams.name + ".html";
$http.get($route.current.templateUrl).then(function (msg) {
$('#view-template').html($compile(msg.data)($scope));
});
}
In the template view, I have a div like this:
<div id="view-template" ng-view></div>
I thought the above code will compile and add the html data to the div but I am receiving the error that says: $ is not a function. What have I got wrong here?
EDIT: After the help from the comments and answers below
SOLUTION:: I was playing around with this a bit more and I went with another solution for this. I added the $route.current.templateUrl to the $scope.theTemplateUrl and then used ng-include in the template file. That did the trick and I also dont need to use the jquery $ function to manipulate the DOM.
Please make a fiddle. The limited scope of this snippet inhibits help :)
By just looking at what you are doing I can only make a few recommendations. But I think your issue lies in .html().
Stop using jQuery while you learn Angular.
Use $scope to change content on page. Instead of
$('#view-template').html($compile(msg.data)($scope));
do this
$scope.viewTemplate = msg.data
then use angular in your view :)
Only use the controller to coordinate the flow of information. There should not be and DOM manipulation happening here. The DOM should reflect a state of the controller.
Define routes in your app config. This is not correct.
$route.current.templateUrl = 'partials/' + $routeParams.name + ".html";
I have some example site in my github repo that you can look at if you want to see a few full sites working: https://github.com/breck421
It seems like you have missed some key parts of Angular. Make sure you take your time and learn it right. It will make you life much easier later.
Thanks,
Jordan
Added for a route provider example:
MyApp.config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'js/views/index.html',
controller: 'AppController',
activeTab: 'home'
})
.when('/home', {
templateUrl: 'js/views/index.html',
controller: 'AppController',
activeTab: 'home'
})
.when('/thing1', {
templateUrl: 'js/views/thing1.html',
controller: 'Thing1Controller',
activeTab: 'thing1'
})
.otherwise({redirectTo: 'home'});
}]);
Then use links like this: Components
EDIT Adding a compile directive per request:
angular.module('CC.directive.Compile', [], function($compileProvider) {
$compileProvider.directive('compile', ['$compile', function($compile) {
// directive factory creates a link function
return function(scope, element, attrs) {
scope.$watch(
function(scope) {
return scope.$eval(attrs.compile);
},
function(value) {
element.html(value);
$compile(element.contents())(scope);
}
);
};
}]);
});
The $ function is defined by jQuery, not angular. Make sure that you have included the jQuery library in order to use $
Say I have an app defined as such:
angular.module('myApp', ['myControllers'])
.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/', {
templateUrl: 'myTemplate.html',
controller: 'MyController'
//???
})]);
How can I say, set $scope.myVariable via this route definition? I want to use this for breadcrumbs.
I think a better way to do what you are doing is to use route parameters. See
https://docs.angularjs.org/api/ngRoute/service/$routeParams
You can make your route something like
/Chapter/:chapterId
and in your controller, inject $routeParams and access the value like so:
$routeParams.chapterId
Turns out you can use the resolve property in the .when method like so:
.when('/', {
templateUrl: 'myTemplate.html',
controller: 'MyController',
resolve: {
test: function() {return "test";}
}
});
Then in my controller I don't access it via the $scope but I inject it like so:
.controller('MyController', ['$scope', 'test', function($scope, test) {
//test contains "test"
}]);
I can access a service such as $routeParams from the controller like so.
angular.module('myModule', []).
controller('myCtrl', ['$routeParams',
'$scope', function($routeParams,
$scope) {
console.log($routeParams['my-route-param']);
}])
But how would I do the same from a template. I tried the following code to no avail.
<h1 ng-hide="$routeParams['my-route-param']">No route param!</h1>
I know you could always save the value to $scope, but I am looking for a cleaner solution.
You can assign routeParams to a property of $scope:
controller('myCtrl', ['$routeParams',
'$scope', function($routeParams,
$scope) {
...
$scope.$routeParams = $routeParams
...
}
and then this would work:
<h1 ng-hide="$routeParams['my-route-param']">No route param!</h1>
Reason for that is every property you are accessing from template should be defined in current scope, which of course is not the case for parameter of controller constructor.
NB: in case of controller as syntax used you would do the same with controller, not scope:
controller('myCtrl', ['$routeParams',
'$scope', function($routeParams,
$scope) {
...
this.$routeParams = $routeParams
...
}
and markup:
<div ng-controller="myCtrl as ctrl">
<h1 ng-hide="ctrl.$routeParams['my-route-param']">No route param!</h1>
It's a bit late, but I had enough of copying $routeParams into my $scope only to be able to use them in my views, so I created a directive to do so.
Let's say you have this routing config:
...
angular.module( 'myApp' ).config( [ '$routeProvider', function( $routeProvider ) {
$routeProvider.when( '/view1/:param1/:param2', {
templateUrl: 'view1/view1.html',
controller: 'View1Ctrl'
});
}])
...
And in your view1.html:
<h1 isteven-rr>$routeParams says: [[param1]] [[param2]]</h1>
If you have this in your URL bar: http://localhost/#/view1/Hello/World!
Then you'll see:
$routeParams says: Hello World!
Fork & learn more: https://github.com/isteven/angular-route-rage
Hope it can help shorten development time! Cheers!