I am trying to use multiple UI-views in my AngularJS app and it is not working as expected. The app is a dashboard.
My directory structure is as follows:
index.html
app/
app.js
dashboard/
dashboard.html
dashboard.js
partials/
business.html
items.html
orders.html
sales.html
login/
login.html
login.js
The problem that I am having is that my index.html file has the following line of code:
<div ui-view></div>
The above line enables my application to show the login.html page and dashboard.html page. Now I want to be able to have partial views in my dashboard.html page and so I have also put the same line of code
<div ui-view></div>
in order to be able to embed partial views in my dashboard page. Instead of embedding though, the page instead just redirects. So for example if I am in my dashboard.html and click on a navigation item such as 'business', I am redirected to partials/business.html instead of the content being embedded.
1) Can I have multiple ui-views embedded within each other?
2) Am I correctly embedding the partial views?
I have scoured the internet but cannot find a solution. Thanks in advance for the help!
You can definitely have multiple embedded views.
Check out these AngularJS UI-Router tutorials: Nested Views and Multiple Named Views.
Let me know if you still have issues after looking them over.
You can define a ui-view inside another ui-view. I have implemented it in the following manner and its pretty straight forward.
Inside index.html I have code:
<div ui-view=""></div>
Then inside user.html I have code
<div ui-view=""></div>
And I have defined a config for displaying my views as
.config(function($urlRouterProvider, $stateProvider) {
var users = {
//Name must be in format Parent.Child
name: 'users',
url: '/user',
templateUrl: 'users/user.html',
controller: 'usersHandler',
data: {
pageTitle: 'Welcome to Users'
},
},
createUsers = {
name: 'users.createUsers',
url: '/createUser',
templateUrl: 'users/createUser.html',
data: {
pageTitle: 'Create Users'
}
},
listUsers = {
name: 'users.listUsers',
url: '/listUsers',
templateUrl: 'users/userLists.html',
data: {
pageTitle: 'Users listing'
}
},
getUserDealer = {
name: 'users.getUserDealer',
url: '/getUserDealer',
templateUrl: 'users/getUserDealer.html',
data: {
pageTitle: 'Users dealer listing'
}
},
editUser = {
name: 'users.editUser',
url: '/editUser',
templateUrl: 'users/editUser.html',
data: {
pageTitle: 'Edit User'
}
};
//Similarly define all the combination you want to separate
//add routes to stateProvider
$stateProvider
.state('users', users)
.state('users.createUsers', createUsers)
.state('users.listUsers', listUsers)
.state('users.getUserDealer', getUserDealer)
.state('users.editUser', editUser);
$urlRouterProvider.otherwise('/user/listUsers');
});
Whats happening is this that user.html is my parent file which is loaded inside index.html and editUser.html, getUserDealer.html and userLists.html etc are its children which I load within user.html using ui-view.
And I provide the links for nested pages as:
<ul class="nav navbar-nav">
<li>NEW USER</li>
<li>GET USER</li>
</ul>
This can be extended to additional parents and their children as per the need.
Hope it helps!!
Related
Now i use visual studio code to do my project. I can build my code without error, but when running, it no show out the content for html file, only have show css like header abd footer. i have click button on header but cannot go to other page.Here is the sample code
code in index.html
<nav>
List
New student
Student feedback
</nav>
Vue router
const router = new VueRouter({
routes: [
{ path: '/home', component: load('home') },
{ path: '/insert', component: load('insert') },
{ path: '/update/:id', component: load('update') },
{ path: '/feedback', component: load('feedback') },
{ path: '*', redirect: '/home' }
]
});
File name and type: _home.html, _insert.html, _update.html, _feedback.html
Can help me see the problem, thank you
I don't think you should edit directly to index.html as Vue is Single Page Application (SPA) framework. Instead, you should use Vue Component for each page.
This video might help you to figure out how to use Vue and Vue Router properly: https://youtu.be/nnVVOe7qdeQ
Edit:
For sake of clarity, Let me build simplified diagram of Vue project for you.
First of all, make sure you create the project via vue cli. It guides you to build your new vue project better.
Let's say we have 3 pages:
Home
About
Another
Each page has its own CSS, HTML (we call it template), and JavaScript in one file, the .vue file. To connect them, we need a first entrance, main.js. Inside of it, we can configure the router.
Inside main.js
import Vue from "vue";
import VueRouter from "vue-router";
import App from "./App.vue";
import HomePage from "./HomePage.vue";
import AboutPage from "./AboutPage.vue";
import AnotherPage from "./AnotherPage.vue";
// This is your router configuration
Vue.use(VueRouter);
const router = new VueRouter({
[
{ path: "/", component: HomePage },
{ path: "/about", component: AboutPage },
{ path: "/another", component: AnotherPage },
],
mode: "history",
});
// Initialize Vue App
new Vue({
router,
render: h => h(App),
}).$mount("#app");
Then, we need to create App.vue and put <router-view /> inside of it.
Inside App.vue source file
<template>
<div id="app">
<router-view />
</div>
</template>
<script>
export default {
// Keep this empty. Except if you
// need to add sidebar or any else.
}
</script>
Now you're ready to create those three pages
Every pages looks like this:
<style scoped>
// Your CSS here
</style>
<template>
<div>
<!-- Your HTML here -->
</div>
</template>
<script>
export default {
data() {
return {
// Your reactive data here
}
},
mounted() {
// Your script here
},
methods: {
// Your functions here
},
}
</script>
That's all I can explain, hope it helps. If I missed something, please don't hesitate to tell me. Thank you!
I have an Angular 1.x project with the following configuration:
Html root:
<base href="/admin/" />
<div ui-view="mainView">
State provider config:
config(['$stateProvider', function ($stateProvider) {
$stateProvider
.state('cats_state', {
url: 'cats',
views: {
'mainView': {
templateUrl: '/app/components/cats/cats.html'
}
}
})
.state('dogs_state', {
url: 'dogs',
views: {
'mainView': {
templateUrl: '/app/components/dogs/dogs.html'
}
}
})
}])
The cats_state and dogs_state states are associated with urls that are relative to /admin/ path and they load a specific html template on the same area. When I click on any of them, the browser url is changed to /admin/cats and/or /admin/dogs. The only issue is: how to reload the same state/template when I manually reload the /admin/cats url? I want to achieve this using angular ui-router only, if possible.
While people are viewing this question (but not answering), I have found the solution: and that is to define the
<base href="/" />
and the urls for various states as:
config(['$stateProvider', function ($stateProvider) {
$stateProvider
.state('cats_state', {
url: '/admin/cats',
views: {
'mainView': {
templateUrl: '/app/components/cats/cats.html'
}
}
})
.state('dogs_state', {
url: '/admin/dogs',
views: {
'mainView': {
templateUrl: '/app/components/dogs/dogs.html'
}
}
})
}])
I didn't quite understood why this is happening, but it works like this. Also, I have noticed that the / path is reloaded first (and therefore all dependencies), and after this, the ui-router somehow resolves the current url, probably based on the states configuration as being the one from the browser's address.
I have created a plunker here with my code, which includes these routes.
'use strict';
var app = angular.module('app', ['ngResource', 'ui.router','ngAnimate', 'ui.bootstrap'])
.controller('Ctrl',function($scope,$log){
// controller code....
})
.config(['$urlRouterProvider','$stateProvider',function($urlRouterProvider,$stateProvider) {
$urlRouterProvider.otherwise('/login');
$stateProvider
.state('home', {
url:'/home',
templateUrl: '/views/home_page.html',
resolve: {
loggedin: checkLoggedin
}
})
.state('admin', {
url:'/admin',
templateUrl: 'views/admin.html',
resolve: {
loggedin: checkLoggedin
}
})
.state('login', {
url:'/login',
templateUrl: 'views/login.html',
});
}]) // end of config()
I am facing problem in routing. I have created login.html file , I am successfully logging in , after login it is redirecting to home_page.html , in this page I have created nav bar and few things. But if I click link admin from home page , it is showing only the admin page content , it is not showing nav bar in admin page. In index.html page I am using ui-view, but still it is not displaying home page's nav bar in other pages.
If I go to other pages other than home_page.html it is not showing nav bar.
If I write nav bar code in index.html then on the login screen also it will display nav bar. On login screen it should not display nav bar. please help me in solving this issue.
If you want to have the nav bar on every page after login, you must use nested views.
Mean, you define a "master" view where you have your nav-bar and define there a container, content (admin, main page) have to go in.
When I look at your source above, you not defined any nested view.
Good description and examples how to do this can be found here.
Cause the explanation would be to long for here, I provide the link.
I retrieve data from back-end and show it in a html page using a controller. When user click a certain link, the other page load according to the link id(here promo page). I want to pass the menu_id to the loading page. I use ngRoute. Below is the html code which I tried,
<li class="table-view-cell" ng-repeat="menu in menuList">
<a class="navigate-right btn-lg" href="#{{menu.link}}/{{menu_id}}">
<span class="{{menu.icon}}"></span>
{{menu.menuName}}
</a>
</li>
Below is the routing,
mobileApp.config(function($routeProvider) {
$routeProvider
.when('/promo/menu._id', {
templateUrl: 'tpl/promo.html',
controller: 'promoController',
activePage: 'promo'
})
Below is the controller for the promo page which I need to retrieve the menu_id,
$http.get(SERVER_URL + '/api/templates/getCategories?appId='+$rootScope.appId+'&mainId='+$routeParams.id)
.success(function(data) {
$scope.requestCategory = data[0];
}).error(function(err) {
alert('warning', "Unable to get templates", err.message);
});
mainModule.config([function($routeProvider) {
$routeProvider.when('/promo/:menu._Id', {
templateUrl : 'tpl/promo.html',
controller : 'promoController',
activePage: 'promo'
});
}
You can define your routing like above, notice the colon before menu._Id. In your controller, you can access menu._Id using $routeParams service as follows:
$routeParams.menu._Id
Thats's it.
It started to work when I changed the routing as below,
.when('/promo/:id', {
templateUrl: 'tpl/promo.html',
controller: 'promoController',
activePage: 'promo'
})
In that case you would have to do following in your controller:
$routeParams.id
I have a page with 2 ui-views, the top view has a form and some controls and the bottom view will be changed by the top view, but defaults to displaying a few tables.
I decided to try and do this initial page all in one state, and I am wondering if this is the correct way in this case. The state is called "tracker" and has the views with content as described above. When the user clicks a button in the top view, I want the bottom view to display alternate content (e.g. a map).
I can figure out how to change state "tracker" (views loaded with "controls.html" and "content.html") to a complete second state ("controls.html" and "map.html").
What I'm confused about is how would I change only the bottom view content#tracker between "contact.html" and "map.html" based on the button state in the top view.
The router is:
(function() {
'use strict';
angular.module('pb.tracker').config(function($stateProvider) {
$stateProvider.state('tracker', {
url: '/tracker',
controller: 'TrackerController as track',
data: {
pageTitle: 'Parcel Tracker',
access: 'public',
bodyClass: 'tracker'
},
views: {
'': {
templateUrl: 'modules/tracker/templates/tracker.html'
},
'controls#tracker': {
templateUrl: 'modules/tracker/templates/tracker-controls.html'
},
'content#tracker': {
templateUrl: 'modules/tracker/templates/tracker-details.html'
}
}
});
});
})();
and the base page's html is
<div class="container">
<div class="row spacer-top-xl">
<div class="col-md-12">
<div ui-view="controls"></div>
<div ui-view="content"></div>
</div>
</div>
</div>
One way out is using $broadcast and $on :
From the top view controller..
$scope.sendBroadcast = function() {
$rootScope.$broadcast('myAction');
}
and from the bottom view controller
$scope.$on('myAction', function() {
//Message received
});
another option may be using a service and $watch on a particular value for change.