I'm having trouble getting my routes to match up with my views. I have the following routes:
.state('tab.account', {
url: '/account',
abstract: true,
views: {
'tab-account': {
templateUrl: 'templates/tab-account.html',
controller: 'AccountController'
}
}
})
.state('tab.account.order', {
url: '/order/:id',
views: {
'order-view': {
templateUrl: 'templates/order-view.html',
controller: 'OrderController'
}
}
})
I have this in templates/tab-account.html
<ion-view title="Account">
<ion-content class="has-header padding">
<h1>Account</h1>
<h2>Your orders</h2>
<div class="card" ng-repeat="booking in bookings">
<div class="item item-text-wrap">
<b><a ng-click="viewOrder(booking.id)">{{ booking.carpark.city }}</a></b> on <b>{{ booking.date | date:'dd.mm.yyyy' }}</b>
</div>
</div>
I have this function in the controller for that view:
$scope.viewOrder = function(id) {
$state.go('tab.account.order', {id:id});
};
Then finally I have this view for the order:
<ion-view ui-view="orderView" title="Order">
<ion-content class="has-header padding">
<h1>Your Order</h1>
</ion-content>
The url seems to work, I end up with #/tab/account/order/1 but it doesn't load that final view!
Cheers in advance!
The ui-router configuration will depend on what you're trying to do.
It looks like you want the account view and the order view to be on separate pages, in which case you won't want it to be an abstract state, since from the ui-router wiki: "An abstract state can have child states but can not get activated itself. An 'abstract' state is simply a state that can't be transitioned to."
I'm not entirely sure you even want a child state for the same reason, since "child states will load their templates into their parent's ui-view." (https://github.com/angular-ui/ui-router/wiki/Nested-States-%26-Nested-Views#nested-states--views).
If this is the case, then you can do something like this:
.state('tab.account', {
url: '/account',
templateUrl: 'templates/tab-account.html',
controller: 'AccountController'
})
.state('tab.order', {
url: '/account/order/:id',
templateUrl: 'templates/order-view.html',
controller: 'OrderController'
})
Here's a plunkr: http://plnkr.co/edit/uuEQcxbWchxQyGV7wMlw?p=preview
The views objects have been removed, since you don't really need them unless you have multiple nested views.
If however you wanted the order view on the same page, then you could do something like this: http://plnkr.co/edit/8Tb1uhVDM0HCW8cgPRfL?p=preview
<ion-view title="Account">
<ion-content class="has-header padding">
<h1>Account</h1>
<h2>Your orders</h2>
<div class="card" ng-repeat="booking in bookings">
<div class="item item-text-wrap">
<b><a ng-click="viewOrder(booking.id)">{{ booking.carpark.city }}</a></b> on <b>{{ booking.date | date:'dd.mm.yyyy' }}</b>
</div>
</div>
<ui-view></ui-view> <!-- Where the child view will load -->
</ion-content>
</ion-view>
app.js:
.state('tab.account', {
url: '/account',
templateUrl: 'tab-account.html',
controller: 'AccountController'
})
.state('tab.account.order', {
url: '/order/:id',
templateUrl: 'order-view.html',
controller: 'OrderController'
})
You'll also probably want to remove your ion-content from the order view template, or else you might get some funky double scroll issues.
Hope this helps! Ui-router is pretty confusing, but their wiki has some great documentation and examples to clear things up.
Related
First of all, I'm sorry for a long question, but it just has to be like that. Unfortunately...
I have a couple of templates and a couple of routing logic, all linked in separate files. For some reason the template I want to load (which depends on the region selected), doesn't load its region template. It loads, if I click it second time. Please note I have tried ever solution from this topic:
Reloading current state - refresh data
Nothing worked for me.
I have managed to resolve one (another region) of them by placing "{reload:true}" inline in the html code, like this:
<a data-ui-sref="uk-web" data-ui-sref-opts="{reload:true}">Energy Consultant</a>
Now I did the same for another template and it is not working. This is my html:
<div class="btn us-btn" data-ng-controller="carCtrlUs">
<script type="text/ng-template" id="careersTplUs.html">
<div class="closer">
<span class="close-me" data-ng-click="ok()">X</span>
</div>
<uib-accordion close-others="true">
<div uib-accordion-group class="modal-body modone panel-default pull-right" is-open="false">
<uib-accordion-heading>
<p class="car-heading">Sales Department <i class="pull-right glyphicon" ng-class="{'glyphicon-chevron-down': status.open, 'glyphicon-chevron-right': !status.open}"></i>
</p>
</uib-accordion-heading>
<ul>
<li><a data-ui-sref="us-web" data-ui-sref-opts="{reload:true}">Energy Consultant</a></li>
<li><a data-ui-sref="us-crm" data-ui-sref-opts="{reload:true}">Client Relationship Manager</a></li>
</ul>
</div>
<div class="modal-body modtwo panel-default pull-right" uib-accordion-group is-open="false">
<uib-accordion-heading>
<p class="car-heading">Marketing Department <i class="pull-right glyphicon" ng-class="{'glyphicon-chevron-down': status.open, 'glyphicon-chevron-right': !status.open}"></i>
</p>
</uib-accordion-heading>
<ul>
<li><a data-ui-sref="us-web" data-ui-sref-opts="{reload:true}">Web Developer</a></li>
<li><a data-ui-sref="us-crm" data-ui-sref-opts="{reload:true}">Marketing Coordinator</a></li>
</ul>
</div>
</uib-accordion>
<div class="show-me" ui-view></div>
</script>
<button class="btn" ng-click="open()" data-ui-sref="us-intro">United States</button>
</div>
app.js:
var app = angular.module('carApp', ['ngAnimate', 'ngSanitize', 'ui.bootstrap', 'ui.router']);
controller, for this template:
app.controller('carCtrlUs', function($scope, $http, $uibModal) {
$http.get('json/jobs-us.json').then(function(response) {
$scope.placeholder = response.data.default;
$scope.specs = response.data.specs;
$scope.open = function() {
var modalContent = $uibModal.open({
templateUrl: 'careersTplUs.html',
controller : 'modalContentCtrlUs',
controllerAs: '$ctrl',
size: 'lg',
backdropClass: 'backdropOver',
openedClass: 'modal-opened',
resolve: {
items: function() { return $scope.specs; },
items2: function() { return $scope.placeholder;}
}
})
console.log($scope.placeholder);
console.log($scope.specs);
console.log($scope.specs.web-dev);
}
});
});
app.controller('modalContentCtrlUs', function($scope, $uibModalInstance, items, items2) {
$scope.specs = items;
$scope.placeholder = items2;
$scope.ok = function() {
$uibModalInstance.close();
}
});
factory.js:
app.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {
$stateProvider
.state("us-intro", {
url:"/intro",
templateUrl: "templates/us/start.html"
})
$stateProvider
.state("us-web", {
url: "/web-developer/",
templateUrl: "templates/us/web-developer.html",
})
.state("us-crm", {
url: "/crm/",
templateUrl: "templates/us/crm.html"
})
/*next .state*/
}]);
Template:
<div ng-repeat="(k, v) in specs.webdev">
<h3>{{::v["job-title"]}}</h3>
<p>{{::v["job-body"]}}</p>
United States Apply Here:
<p>{{::v["job-apply"]}}</p>
</div>
As you can see I'm using ui-bootstrap (modal and accordion, since it is all in a modal window).
What can I do to make it refresh instantly? I'm stuck for days on this and it is frustrating... What am I doing wrong here?
EDIT: Please note that I know "::" is for one-way data binding. I've tried without it and the result is the same. I can probably resolve this by placing the data in question in the .json file, but that would really be an ugly hack.
<div ng-repeat="(k, v) in specs.webdev">
<h3>{{::v["job-title"]}}</h3>
<p>{{::v["job-body"]}}</p>
United States Apply Here:
<p>{{::v["job-apply"]}}</p>
</div>
The "::" avoid data binding to reduce digest cycle. Try to remove them.
<a data-ui-sref="uk-web" data-ui-sref-opts="{reload:true}">Energy Consultant</a>
// it should be
<a data-ui-sref="us-web" data-ui-sref-opts="{reload:true}">Energy Consultant</a>
I have solved this..What I wanted to do is to make the "URL" the same. I have changed the url to manifest the region by the region code, so it is working now.
For example:
UK:
$stateProvider
.state("de-web", {
url: "/web-developer-de",
templateUrl: "templates/de/web-developer.html",
})
.state("de-crm", {
url: "/crm-de",
templateUrl: "templates/de/crm.html"
})
Italy:
$stateProvider
.state("it-web", {
url: "/web-developer-it",
templateUrl: "templates/it/web-developer.html",
})
.state("it-crm", {
url: "/crm-it",
templateUrl: "templates/it/crm.html"
})
United States:
$stateProvider
.state("us-web", {
url: "/web-developer-us",
templateUrl: "templates/de/web-developer.html",
})
.state("us-crm", {
url: "/crm-us",
templateUrl: "templates/de/crm.html"
})
Although this works, I'm not happy. How can it be achieved that the templates are being loaded into the same url?
I've pretty much used the top solution from UI-Router multiple named views not working with my angular app, but my ui-view does not seem to be updating, but rather just disappearing altogether. There must be some really small detail I'm missing that I've been stuck on for a long time...
I have an index.html page, with a [div ui-view=""] that is replaced on the home state. This ui-view (frontpage.html) has another [div ui-view="search-result"] which I'm hoping gets updated (change text to "successful template replacement") from a state change, but when the state changes, the entire [div ui-view=""] from index.html disappears instead when the search button is clicked.
All relevant script tags are included in my index.html.
index.html:
<body ng-app="...">
<div class="container">
<div ui-view=""></div>
</div>
app.js:
angular.module('...', [ 'ui.router','ui.bootstrap']).
config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('main', {
url: "/",
templateUrl: "/app/states/frontpage/frontpage.html"
})
.state('search', {
url : "/search/:query",
views: {
'search-result#search': {
template: 'successful template replacement'
}
}
}).run(function(){});
frontpage.html:
<div class="row" ng-controller="MainController">
some stuff here
<div class="col-xs-9">
<input type="text" class="inline" ng-model="searchText" placeholder="Search..."></input>
<button class="btn btn-default inline" type="button" ng-click="search()">Search</button>
<div ui-view="search-result"></div>
</div>
</div>
mainCtrl.js
angular.module('...')
.controller('MainController', ['$scope','$state', function($scope,$state) {
$scope.searchText;
$scope.search = function(){
console.log('going to state search with searchText: ' + $scope.searchText);
$state.go('search',{query:$scope.searchText});
}
}]);
In case that 'search' state should go to template of the 'main' ... it must be its child (check the parent: 'main')
.state('main', {
url: "/",
templateUrl: "/app/states/frontpage/frontpage.html"
})
.state('search', {
parent: 'main', // parent is main, named view will find its target
url : "/search/:query",
views: {
'search-result#search': {
template: 'successful template replacement'
}
}
}
I can't seem to dynamically update my ui-view with ng-repeat. Is what I'm trying to do even possible? The reason I say this is because if I place any static objects in the intro.html it gets displayed..
Thanks for the help in advance,
JS
}).state('app.register', {
url: '/register',
views: {
'menuContent': {
templateUrl: 'app/register/register.html',
controller: 'RegisterController'
}
}
}).state('app.register.intro', {
url: '/intro',
templateUrl: 'app/register/intro.html'
register.html
<ion-view view-title="Register">
<ion-content class="has-header">
<ui-view>
</ui-view>
</ion-content>
</ion-view>
intro.html
<div ng-repeat="value in items">
value
</div>
The first thing I noticed is your 'intro.html' file is missing a closing '>' tag for your first div.
Following is my simple routes in app.js -
.state('signup', {
url: '/signup',
templateUrl: 'templates/signup.html',
controller: 'signupCtrl'
})
.state('profile', {
url: '/profile',
abstract: true,
templateUrl: 'templates/profile.html',
})
.state('profile.init', {
url: '/profile-init',
templateUrl: 'templates/profile-init.html'
})
I created a button in signup page on click which should take the user to profile-init page code - $state.go('profile.init')
in profile.html I placed -
<ion-content style="background: #c3c3c3"></ion-content>
in profile-init.html page -
<ion-header-bar class="bar-positive">
<h1 class="title">Profile</h1>
</ion-header-bar>
<div class="row">
<div class="col col-10"></div>
<div class="col col-80 padding">
Thanks for showing your interest
</div>
<div class="col col-10"> </div>
</div>
<ion-footer-bar class="bar-stable">
<button class="button button-clear" ng-click="hello()">Forward</button>
</ion-footer-bar>
But it is moving to /#/profile/profile-starter page but only a background color is coming not text, though I checked the browser console template is loading, let me know what I am doing wrong here.
Create ion-nav-view
<ion-nav-view name="profile"></ion-nav-view>
and modify routes in app.js
.state('profile.init', {
url: '/profile-init',
views: {
'profile': {
templateUrl: 'templates/profile-init.html'
}
}
})
Can't comment yet, and not available to test it but I think you need to use dot ('.') in your file name:
templateUrl: 'templates/profile.init.html'
And of course change the file name too.
so i have been following a tutorial on how to use AngularJS ui route. I manage to get the views working just fine. However in trying to get the states to work and its just not working. I followed the tutorial exactly but for some reason my states to just show up. Hopefully someone can help me out.
Scirpt.js
var routerApp = angular.module('routerApp', ['ui.router']);
routerApp.config(function($stateProvider, $urlRouterProvider) {
// For any unmatched url, redirect to /home
$urlRouterProvider.otherwise('/home');
$stateProvider
.state('home', {
url: '/home',
templateUrl: 'views/home.html',
controller: 'homeCtrl'
})
.state('home.list', {
url: '/list',
templateUrl: 'views/partial-home-list.html',
controller: function($scope) {
$scope.dogs = ['Bernese', 'Husky', 'Goldendoodle'];
}
})
.state('home.paragraph', {
url: '/paragraph',
template: 'I could sure use a drink right now.'
})
.state('about', {
url: '/about',
templateUrl: 'views/about.html',
controller: 'aboutCtrl'
})
.state('/views/about', {
// Figure out later
});
});
index.html
<!-- Page Content -->
<div id="page-content-wrapper" ng-app="routerApp">
<div class="container-fluid">
<div class="row">
<div class="col-lg-12">
<h1>Content Page</h1>
<p>This is where the template of the vast amount of pages will be loaded. This will keep it a single page applcatino. The
main page will inject the html that needs to be loaded to the user. While the top nav bar will allow the user to
view the rest of the website, which will be separate pages
</p>
<p>Make sure to keep all page content within the <code>#page-content-wrapper</code>.</p>
Toggle Menu
</div>
</div>
</div>
<!-- Angular Template, this is where content will be injected -->
<div ng-include="pages"></div>
<div ui-view></div>
</div>
</div>
home.html
<div class="jumbotron text-center">
<h1>The Homey Page</h1>
<p>This page demonstrates <span class="text-danger">nested</span> views.</p>
<a ui-sref=".list" class="btn btn-primary">List</a>
<a ui-sref=".paragraph" class="btn btn-danger">Paragraph</a>
</div>
partial-home-list.html
<div>
<ul>
<li ng-repeat="dog in dogs">{{ dog }}</li>
</ul>
</div>
Plunker
http://plnkr.co/edit/cN5uM1m20DHGps8cZgzt
Since you are using nested states and views ("home.list" is nested inside "home"), you need to include <div ui-view></div> in your home.html as well.
For further information: https://github.com/angular-ui/ui-router/wiki/Nested-States-&-Nested-Views
Good luck! :)