Reputation: 841
Whenever I start the site it works fine, but all the links are broken. They work, I can click on them and it directs me to the right URL but no content relative to that specific page shows up. But if I were to copy and paste that URL into a different browser window, itd redirect me back home as if that URL didnt exist... Heres my apps JS file:
var app = angular.module("myApp", ['dotjem.routing']);
app.config(function($routeProvider, $stateProvider){
$routeProvider.otherwise({redirectTo: '/home'});
$stateProvider.state('home', {route: '/home', views:{"main":{template:"template/guide.html"}}});
$stateProvider.state(['$register', '$http', function(reg, $http){
return $http.get("api/getpages.php").success(function(data){
for(element in data){
reg(data[element].pagename, {route: data[element].path, view:{"main":{template:data[element].templateUrl}}});
}
});
}]);
});
Im getting this error when I try and click on pages after refreshing on a page that I clicked ona link to previously, then all the links on the menu bar go dead:
Error: Could not locate 'mybuilds' under '$root'. at Error () at a.lookup (http://url.co.uk/angular/myblog/scripts/angular-routing.min.js:8:23732) at a.resolve (http://url.co.uk/angular/myblog/scripts/angular-routing.min.js:8:23975) at Object.J.url (http://url.co.uk/angular/myblog/scripts/angular-routing.min.js:8:18670) at f (http://url.co.uk/angular/myblog/scripts/angular-routing.min.js:8:29260) at i (http://url.co.uk/angular/myblog/scripts/angular-routing.min.js:8:29537) at link (http://url.co.uk/angular/myblog/scripts/angular-routing.min.js:8:29694) at nodeLinkFn (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.12/angular.js:6230:13) at compositeLinkFn (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.12/angular.js:5640:15) at compositeLinkFn (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.12/angular.js:5643:13)
<a sref="'{{link.path}}'" class="ng-binding">
Is how my link works.
A JSON sample if it helps:
[{"id":1,"displayName":"Tour","pagename":"home","templateUrl":"templates\/tourview.html","path":"\/home"}]
I have also tried putting in the links manually but still no joy.
<div jem-view="main"></div>
Is my view. The home page works perfectly.
Upvotes: 0
Views: 204
Reputation: 3412
One of the things i can easily spot that seems incorrect is your use of sref, as you point it towards the route rather than the state, sref is meant to make it easier to manage states and their URLS in that you can link directly to them rather than having to duplicate the route in multiple places.
So rather than what you did, you should just say <a sref="link.pagename">
(it's a regular binding, we use '' around it when we make static links, just like ng-include) assuming you have a service or something where you store those links and they are just the json object you got from the server.
Working example: http://plnkr.co/edit/M9Ey6VnJn7wHLqNdHmwh?p=preview
To look at the use of sref
, we can have a look at how it's done in that sample:
app.service('menu', function() {
var self = this;
self.register = function(title, state) {
self.items.push({
title: title, state: state
});
}
self.items = [];
});
As I said, you probably have some sort of menu service, in the sample I called this menu, that isn't the best name, but it serves it's purpose in the demo. This is where we register links.
Note that we CAN actually access the whole internal "state" tree, BUT that is not an official API. (it's exposed for testing). So instead, we simply manage it outside. This will make it possible to categorize items as well etc. as we might not want every single state to figure on the top bar.
app.config(['$stateProvider',
function(sp) {
sp.state('home', {
route: '/',
views: {
"main": {
template: "template/guide.html"
}
}
});
sp.state(['$register', '$http', 'menu',
function(register, http, menu) {
// This is just a workaround, home is a static state, but we can't access the
// menu service in the provider so we just register it here. There is 2 "correct"
// aproaches to this problem in my mind:
// - User a menu provider which can be used along static state registration.
// - Just write static references in the HTML.
//
// What I did here was just easier for this sample.
menu.register('HOME', 'home');
return http.get("routes.json").success(function(data) {
angular.forEach(data, function(state){
// Register the "state link" with the menu service.
// All we need here is it't title and the state name.
menu.register(state.displayName, state.pagename);
// Register the actual state. I would have prefered different names here
// but thats preference.
register(state.pagename, {
route: state.path,
views: { main: { template: state.templateUrl } }
});
});
});
}
]);
}
]);
Won't elaborate much more on this that the comments does.
app.controller('siteController', ['$scope', '$state', 'menu',
function($scope, $state, menu) {
//Some ugly bindup just so we can demonstrate that the latebound registration works.
this.menu = menu;
this.state = $state;
}
]);
I like to have a global site controller in my angular apps, in this example we just use it to expose the menu service and state service directly, that is not a recommended approach, but its a quick approach for a demo.
<body ng-controller="siteController as site">
...
<ul class="nav navbar-nav">
<li ng-repeat="page in site.menu.items"
ng-class="{ active: site.state.isActive(page.state) }">
<a sref="page.state">{{ page.title }}</a>
</li>
</ul>
And finally an example of how we build the menu.
Upvotes: 1