This is my first time using UI Router inside AngularJS project. I have a problem where when I click a link to view a post, it doesn't show up.
The post template is not showing and I'm still at the home page. I can see the URL flashing like http://localhost:8000/#/posts/1 and attempt to change, but, it goes back to http://localhost:8000/#/home.
Plunker: http://plnkr.co/edit/KV6lwzKUHrIZgVWVdrzt
What I am missing here?
Note 1: I already read UI Router documentation and I think I'm not missing anything.
Note 2: I'm following this tutorial (thinkster).
Note 3: I'm using SimpleHTTPServer python -m SimpleHTTPServer 8000 command to serve this project.
This is my app.js:
app.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider){
$stateProvider
.state('home', {
url: '/home',
templateUrl: '/home.html',
controller: 'MainCtrl'
})
.state('posts', {
url: 'posts/:id',
templateUrl: '/posts.html',
controller: 'PostsCtrl'
});
$urlRouterProvider.otherwise('home');
}]);
...
app.controller("PostsCtrl", ["$scope", "$stateParams", "postsFactory", function($scope, $stateParams, postsFactory){
// grab the right post from postsFactory posts array
$scope.post = postsFactory.posts[$stateParams.id];
console.log($scope.post);
}]);
And this is my index.html:
<ui-view></ui-view>
...
<script type="text/ng-template" id="/posts.html">
<div class="page-header">
<h3>
<a ng-show="post.link" href="{{post.link}}">
{{post.title}}
</a>
<span ng-hide="post.link">
{{post.title}}
</span>
</h3>
</div>
</script>
Issue in your code is in your router config for posts state. It should be like below. URL should be /posts/:id instead of posts/:id.
$stateProvider
.state('posts', {
url: '/posts/:id',
templateUrl: '/posts.html',
controller: 'PostsCtrl'
});
You are basically missing / slash at the start of your posts state URL, because of / is missing it was redirecting to .otherwise rule of $urlRouterProvider
Code
.state('posts', {
url: '/posts/:id',
templateUrl: '/posts.html',
controller: 'PostsCtrl'
});
You also need to add $locationProvider.html5Mode(true); in the app.config block and <'base href="/"'> in the head section of your HTML file.
Otherwise, the #/posts/:id routing won't work.
Related
I use for testing python simpleserver to test my angular app. I new to ui.router and trying to get index.html work properly and when trying to go home using e.g.
<a class="navbar-brand" ui-sref="/">MyApp</a>
To navigate back to home or index.html
Code
"use strict";
var mainApp = angular.module('mainApp', ['ui.router']);
mainApp.config(function($stateProvider, $urlRouterProvider, $locationProvider) {
$urlRouterProvider.otherwise('/#');
$stateProvider
.state('/', {
url: '/',
templateUrl: 'index.html',
controller: 'mainController'
});
});
mainApp.controller('mainController',
function($state, $log, $scope, $rootScope, $http) {
$scope.test = 'foobar';
}
);
Any help would be appreciated to fix it.
Problem Plunkr
You are rendering index.html again inside your ui-view div, so techically you should have html that would have your home page content
myHomePage.html
<div class="home-page">
Its home page
{{test}}
</div>
State
$stateProvider
.state('/', { //<-- here it should be some stateName rather than using `/`
url: '/',
templateUrl: 'myHomePage.html', //<--changed here
controller: 'mainController'
});
Plunkr
I am trying to display content using Angular, angular UI-Router, and without relying on $scope.
In my mainController, I don't have any issues using directive likes ng-repeat. But I don't know how to access information from my postsController.
I know that I am pulling the correct data in my controller since console.log shows the correct post object. Now I just need to know how to access it.
index.html
<script type="text/ng-template" id="/posts.html" >
{{ }} // What do I put here?
</script>
app.js
app.config([
'$stateProvider',
'$urlRouterProvider',
function($stateProvider, $urlRouterProvider) {
...
.state('posts', {
url: '/posts/{id}',
templateUrl: '/posts.html',
controller: 'postsController'
});
$urlRouterProvider.otherwise('home');
}
]);
app.js
app.controller('postsController', [
'$stateParams',
'posts',
function($stateParams, posts) {
var vm = this;
vm.post = posts.posts[$stateParams.id];
console.log(vm.post);
}
]);
You state will be using controllerAs so you need to define controller as below. And by using alias of your controller you could show data on view.
.state('posts', {
url: '/posts/{id}',
templateUrl: '/posts.html',
controller: 'postsController as postCtrl'
});
View
<script type="text/ng-template" id="/posts.html" >
<ul>
<li ng-repeat="p in postCtrl.post">{{p}}</li>
</ul>
</script>
You should have latest version like 0.2.0+ version of ui-router to declare controllerAs like I suggested, for older version you could use #RadimKöhler suggestion.
You should use declaration controllerAs:
.state('posts', {
url: '/posts/{id}',
templateUrl: '/posts.html',
controller: 'postsController',
controllerAs: 'vm' // this will be injected into $scope
});
and the view consume it like this:
{{vm.data | json }}
In my angular project the user accepts a EULA then get automatically redirected to their dashboard, however, on this redirect the DashboardController seems to be being called twice, the DashboardController is being called on the route itself, I have checked to see if I have accidently called it again in the template but I havn't. Below is my route & controller. It doesn't appear to matter if I access the URL directly or via the redirect on the EULA controller, I get the same result.
The routes
.config(function($httpProvider, $stateProvider, $urlRouterProvider) {
$httpProvider.interceptors.push('httpRequestInterceptor');
$urlRouterProvider.otherwise('/');
$stateProvider
.state('login', {
url: '/',
templateUrl: 'templates/login.html',
data: {
requireLogin: false
}
})
.state('eula', {
url: '/eula',
templateUrl: 'templates/eula.html',
data: {
requireLogin: true
}
})
.state('dashboard', {
url: '/groups',
templateUrl: 'templates/dashboard.html',
data: {
requireLogin: true
}
})
});
The controller:
App.controller('DashboardController', ['$scope', 'RequestService', '$state', '$rootScope', function($scope, RequestService, $state, $rootScope){
alert('test');
}]);
Any ideas?
ADDED MY HTML AS PER COMMENTS
index.html
<body ng-app="App">
<ion-nav-bar class="bar-positive nav-title-slide-ios7" align-title="center">
<ion-nav-back-button class="button-icon ion-arrow-left-c"></ion-nav-back-button>
</ion-nav-bar>
<ion-nav-view class="slide-left-right"></ion-nav-view>
<ui-view></ui-view>
</body>
dashboard.html
<div class="groups" ng-controller="DashboardController">
<ion-view title="App">
<ion-nav-buttons side="right">
<a ui-sref="groupcreate"><span class="icon ion-ios-plus-outline"></span></a>
</ion-nav-buttons>
<ion-content class="padding">
<div class="row">
<div class="col-50" ng-repeat="group in groups">
{{ group }} 1
</div>
</div>
</ion-content>
</ion-view>
</div>
If you are using ui-router you don't have to use ng-controller. You have used it in your dashboard.html, another is generated by ui-router - that's why it is hit twice.
Ok so after a long time debugging and check stuff out, I found out that it was an issue relating to the Nav Bar in ionic, essentially, I was calling <ui-view></ui-view> & <ion-nav-view></ion-nav-view> on the same page, so basically doubling up on my views which in turn was calling the controller twice.
I know this has been answered already as well, but I wanted to add my fix for the exact same problem.
My controllers were also being called twice, but in my case I had to comment out the ng-controller settings in various files:
My config function in the main app.js
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('splash', {
url: "/",
templateUrl: "app/splash/splash.html"
// controller: 'SplashCtrl'
})
Since I was already calling it in the markup:
<ion-view view-title="TickerTags" ng-controller="SplashCtrl as splash">
<ion-content class="splash">
The controller key inside of my Directives
angular
.module('tagsPanelDirective', [])
.controller('TagsPanelCtrl', TagsPanelCtrl)
.directive('tagsPanel', tagsPanel);
function tagsPanel() {
var directive = {
templateUrl: "app/tags/tagsPanel.html",
restrict: "E",
replace: true,
bindToController: true,
// controller: 'TagsPanelCtrl as tagsPanel',
link: link,
scope: false
};
return directive;
function link(scope, element, attrs) {}
}
Again since I was already calling it from within the template markup:
<section class="tags-panel" ng-controller="TagsPanelCtrl as tagsPanel">
Hi I am going to start a project.
In tablet page contains list of items on left side and item detail on right side as shown in below image.
In mobile It shows list of items on one page and detail of activity on another page, like below images.
I have used AngularJs to implemented this application like this(pseudo code)
Index.html
<html>
<head></head>
<boby>
<ui-view></ui-view>
</body>
</html>
List.html
<ul><li ng-repeat='item in items' >{{item.title}}</li></ul>
<div id="middleContent" ui-view style="padding-left: 320px;"></div>
detail.html
<div>Acitivity detail <div>
config.js
app = angular.module('MyApp', ['ui.router']);
app.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider.state('List', {
url: '/List',
templateUrl: 'Partial/List.html',
controller: 'ListController'
})
$stateProvider.state('Detail', {
url: '/Detail/:id',
templateUrl: 'Partial/Detail.html',
controller: 'DetailController'
})
$stateProvider.state('TabletList', {
url: '/TabletList',
data: { 'parent': 'tablet' },
templateUrl: 'Partial/List.html',
controller: 'ListController'
})
$stateProvider.state('TabletList.Detail', {
url: '/Detail/:id',
templateUrl: 'Partial/Detail.html',
controller: 'DetailController',
})
})
In Controller.js
app.controller('ListController',function(){
if($(window).width() > mobileView )( $state.go('TabletList.Detail'))
})
In List.html I have use next view
<div id="middleContent" ui-view style="padding-left: 317px;"></div>
It get loaded in case of tablet . otherwise it is useless there.
Is there some simple way to handle this scenario. please help
with regards
I'm really new to Angular and I have a little question about sending a template or URL into a ng-view. But the way I intend to do I may have to ng-view in my base template.
When my template base is like this:
<body>
<div ng-view></div>
</body>
And my JS looks like:
var app = angular.module('myApp',[])
.config(['$routeProvider', '$locationProvider', '$httpProvider', function($routeProvider, $locationProvider, $httpProvider) {
$routeProvider
.when('/home', {
templateUrl: '/contato'
})
(...)
Works fine loading URL inside ng-view when I have only ONE ng-view case, HOW ABOUT IF I need to have more then one ng-view to load ? (like: ng-view="area1" and ng-view="area2")
I've tried in each $routeProvider, but won't work:
$routeProvider
.when('/home', {
area1: {templateUrl: '/path1'},
area2: {templateUrl: '/path2'}
})
How would be the right way to set each ng-view separately?
Appreciate any help! Thanks.
Unfortunately, as you know now, you cannot have more than one ng-view on your page. You should have a look at UI-Router from AngularUI which does exactly what you are looking for (https://github.com/angular-ui/ui-router).
An example from their doc (https://github.com/angular-ui/ui-router#multiple--named-views):
setup
var myApp = angular.module('myApp', ['ui.router']);
html
<body>
<div ui-view="viewA"></div>
<div ui-view="viewB"></div>
<!-- Also a way to navigate -->
<a ui-sref="route1">Route 1</a>
<a ui-sref="route2">Route 2</a>
</body>
template 1
<h1>State 1</h1>
template 2
<h1>State 2</h1>
js
myApp.config(function($stateProvider, $routeProvider) {
$stateProvider
.state('index', {
url: "",
views: {
"viewA": { template: "index.viewA" },
"viewB": { template: "index.viewB" }
}
})
.state('route1', {
url: "/route1",
views: {
"viewA": { templateUrl: "route1.viewA.html" },
"viewB": { templateUrl: "route1.viewB.html" }
}
})
.state('route2', {
url: "/route2",
views: {
"viewA": { templateUrl: "route2.viewA.html" },
"viewB": { templateUrl: "route2.viewB.html" }
}
});
});
Here you could specify a controller at the state level, that would be effective for both views, or at the view level, in order to set two different controllers.
Edit: Live demo from ui-router docs (http://plnkr.co/edit/SDOcGS?p=preview)
Basically you can't have two ng-view. Have a look at this SO question:
You can have just one ng-view.
You can change its content in several ways: ng-include, ng-switch or mapping different controllers and templates through the routeProvider.