I want to keep a menu html showing all the time.
and mapaBase with their respective html and controller, too.
I want to extend the functionality of controladorMapa to the inicial and movilpedido state.
I got a blank screen
.state('menu', {
url: "/menu",
abstract: true,
templateUrl: "templates/menu.html"
})
.state('menu.mapaBase', {
url: "/mapaBase",
abstract: true,
templateUrl: "templates/mapaBase.html",
controller: 'controladorMapa'
})
.state('menu.mapaBase.inicial', {
url: "/inicial",
templateUrl: "templates/mapaInicial.html"
controller: 'controladorInicial'
})
.state('menu.mapaBase.movilPedido', {
url: "/movilPedido",
templateUrl: "templates/movilPedido.html"
controller: 'controladorMovil'
})
You can create a directive to extend html and some functionality.
https://docs.angularjs.org/guide/directive
But if you just want a fixed menu maybe the best choice is create a template for your app/website instead of a component to add everywhere.
Related
I have a working app though I am changing the architecture, cutting views down into smaller, more manageable documents. I currently have a state with a child state.
.state('patents', {
url: '/patents',
templateUrl: 'p3sweb/app/components/patents/views/list-patents.htm',
controller: 'listPatentsCtrl',
controllerAs: '$ctrl',
})
.state('patents.patent', {
url: '/{patentId}/:patentHref',
templateUrl: 'p3sweb/app/components/patents/views/patent-item.htm'
})
When I click on a table row in state patents, up pops patents.patent view below it.
I have now changed it so the child patents.patent state has multiple views like so:
.state('patents.patent', {
url: '/{patentId}/:patentHref',
templateUrl: 'p3sweb/app/components/patents/views/patent-item.htm',
views: {
'#': {
templateUrl: 'p3sweb/app/components/patents/views/patent-item.htm'
},
'patentinfo#patents.patent': {
templateUrl: 'p3sweb/app/components/patents/views/ui-views/patent-info.htm',
controller: 'patentInfoCtrl',
controllerAs: '$ctrl'
},
'patentcostanalysis#patents.patent': {
templateUrl: 'p3sweb/app/components/patents/views/ui-views/patent-costanalysis.htm',
controller: 'patentCostAnalysisCtrl',
controllerAs: '$ctrl'
},
'patentrenewals#patents.patent': {
templateUrl: 'p3sweb/app/components/patents/views/ui-views/patent-renewals.htm',
controller: 'patentRenewalsCtrl',
controllerAs: '$ctrl'
}
})
When I now click on the row in state patents, the patents.patent view replaces the parent view. So instead of displaying below it, it's the only view displayed.
Question
How do I resolve the issue that has occurred now I have included multiple views in patents.patent state?
So it turns out, after reading ui-router wiki, using # creates an absolute path, and I wasn't targeting the view in the parent state patents.
So instead of
views: {
'#': {
templateUrl: 'p3sweb/app/components/patents/views/patent-item.htm'
}
It should of been
views: {
'#patents': {
templateUrl: 'p3sweb/app/components/patents/views/patent-item.htm'
}
I am attempting to set up nested views loading in the parent views via state children but I'm not sure if I'm going about this the correct way.
So far, I have:
$stateProvider
.state('splash', {
url: '/splash',
templateUrl: 'system/templates/splash.html',
controller: ""
}).state('home', {
url: '/',
templateUrl: 'system/templates/home.html',
controller: ""
}).state('user', {
url: '/user/:user?',
templateUrl: 'system/templates/user.html',
controller: "userController"
}).state('user.data', {
views: {
"#vdata" : {
templateUrl: 'system/templates/user.html',
controller: "userController"
}
}
})
The "user" parent state recieves :user? the correct way, however when I try to navigate via $state.transitionTo();, I get the response of
Param values not valid for state 'user.data'. I have an unnamed view with the pattern
<div ui-view></div>
set as the parent. Then nested in the user template, I have a ui-view called "vdata". According to the documentation, if I target #vdata, the pages requested should be loading there.
How can I get the nested view to inherit the parameter from the parent view?
Use resolve and inject user on controller. The resolved references are shared betwen parent child states.
$stateProvider
.state('splash', {
url: '/splash',
templateUrl: 'system/templates/splash.html',
controller: ""
}).state('home', {
url: '/',
templateUrl: 'system/templates/home.html',
controller: ""
}).state('user', {
url: '/user/:user?',
templateUrl: 'system/templates/user.html',
controller: "userController",
resolve:{
user: function($stateparams){
return $stateParms.user;
}
}
....
On usercontroller inject user
I am creating a web app to help students in science, history and math. When you first land on the site I have a home/landing page. When you click get started I route to /exam/instructions. Each of my steps instructions, math and science our templates that I load into the ui-view="exam-detail". Currently the whole ui-view loads when I navigate to and from instructions through sciences. Ideally I simply want an area for pagination and an area for the subject matter and only want the ui-view="exam-detail" to update with the correct template.
I have not used UI-Router at all and any assistance would be greatly appreciated.
index.html
<div ui-view></div>
state-exam>exam.html
<div class="state-exam">
<nav ui-view="exam-pagination"></nav>
<section ui-view="exam-detail"></section>
</div>
route.js
(function() {
'use strict';
angular
.module('studentPortal')
.config(routeConfig);
function routeConfig($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
url: '/',
templateUrl: 'app/main/main.html',
controller: 'MainController',
controllerAs: 'main'
})
.state('exam', {
url: '/exam/:step',
abstract: true,
templateUrl: 'app/state-exam/exam.html',
controller: 'ExamController',
controllerAs: 'examController',
})
.state('exam.instructions', {
url: '/instructions',
views: {
'exam-pagination':{
templateUrl: 'app/state-exam/exam-pagination.html'
},
'exam-detail' : {
templateUrl: 'app/state-exam/exam-instructions.html'
}
}
})
.state('exam.math', {
url: '/math',
views: {
'exam-pagination':{
templateUrl: 'app/state-exam/exam-pagination.html'
},
'exam-detail' : {
templateUrl: 'app/state-exam/exam-math.html'
}
}
});
$urlRouterProvider.otherwise('/');
}
})();
There is a working plunker
There is a similar Q & A in fact, with working plunker:
Angular UI Router - Nested States with multiple layouts
Solution here, is to move the static view from child to parent. It won't be reloaded for each child (view is reloaded only if parent state is changed). We will use absolute naming (see included links for more details)
So this is the code adjustment
.state('exam', {
url: '/exam/:step',
abstract: true,
// the root view and the static pagination view
// will be defined here, so we need views : {}
views: {
'':{
templateUrl: 'app/state-exam/exam.html',
controller: 'ExamController',
controllerAs: 'examController',
},
// absolute naming targets the view defined above
'exam-pagination#exam':{
templateUrl: 'app/state-exam/exam-pagination.html'
},
}
})
.state('exam.instructions', {
url: '/instructions',
views: {
// 'exam-pagination':{}, // defined in parent
'exam-detail' : {
templateUrl: 'app/state-exam/exam-instructions.html'
}
}
})
.state('exam.math', {
url: '/math',
views: {
// 'exam-pagination':{}, // defined in parent
'exam-detail' : {
templateUrl: 'app/state-exam/exam-math.html'
}
}
});
Also check this to get more details about absolute view naming
Angular UI router nested views
Angular-UI Router: Nested Views Not Working
The working example is here
Let's say I have two states:
.state('page1', {
url: '/page1',
templateUrl: 'pages/templates/page1.html',
controller: 'page1'
})
.state('page2', {
url: '/page2',
templateUrl: 'pages/templates/page2.html',
controller: 'page2'
})
They both have the element <div id="clickme'>DO IT</div>.
In one controller I have:
$("body").on('click', '#clickme', function(e) { alert("clicked"); });
But not on the other controller.
What is the most effective way to restart my bindings if I have a lot of these separately going on within my different controllers?
I don't want them to be active when I switch state's because some things may overlap or just want to make sure nothing overlaps.
The most efficient way is not to do it at all. As the comments have pointed out, you probably shouldn't be using jQuery in your Angular code. Its just not the Angular way.
What you probably want is some directives:
.state('page1', {
url: '/page1',
template: '<page1>',
controller: 'page1'
})
.state('page2', {
url: '/page2',
template: '<page2>',
controller: 'page2'
})
And then in your directive code you will have something like
.directive('page1', function() {
return {
template: '<div ng-click="doIt()">DO IT</div>',
link: function($scope){
$scope.doIt = function(){...}
}
};
});
I have a UI-Router document set up to show the "pages" sections of a demo.
(function() {
'use strict';
angular.module('pb.ds.pages').config(function($stateProvider) {
$stateProvider.state('pages', {
abstract: true,
url: '/pages',
templateUrl: 'modules/pages/templates/pages.html',
controller: 'PagesController as pages',
data: {
pageTitle: 'Pages',
access: 'public',
bodyClass: 'pages'
}
})
.state('pages.signin', {
url: '/signin',
templateURL: 'modules/pages/templates/signin.html',
controller: 'SignInController as signin'
})
.state('pages.forgotpassword', {
url: '/forgotpassword',
templateURL: 'modules/pages/templates/forgotpassword.html',
controller: 'ForgotPasswordController as forgot'
})
.state('pages.404', {
url: '/404',
templateURL: 'modules/pages/templates/404.html',
controller: '404Controller'
});
});
})();
The parent state, "pages" has the ui-view on it, but otherwise I don't need to "show" it. I am only interested in showing its children, such as pages.signin or pages.forgotpassword.
Typing in the url "/forgotpassword" bounces me back to my homepage, which is the "otherwise" state in my app.module.js
// UI ROUTER CONFIG
angular.module('app').config(function($stateProvider) {
$stateProvider.state('otherwise', {
url: '*path',
template: '',
controller: function($state) {
$state.go('dashboard');
}
});
});
No errors in console, and all the pages in question are linked in my index.html.
I'm sure I must have missed something obvious. Any clues?
UPDATE
If I enter /pages/forgotpassword it does go to the correct path but the view is not being populated by the template...
There is a working plunker
We have to adjust state definition like this:
$stateProvider.state('pages', {
abstract: true,
//url: '/pages',
templateUrl: 'modules/pages/templates/pages.html',
controller: 'PagesController as pages',
data: {
pageTitle: 'Pages',
access: 'public',
bodyClass: 'pages'
}
})
.state('pages.signin', {
url: '/signin',
// templateURL: 'modules/pages/templates/signin.html',
templateUrl: 'modules/pages/templates/signin.html',
controller: 'SignInController as signin'
})
.state('pages.forgotpassword', {
url: '/forgotpassword',
//templateURL: 'modules/pages/templates/forgotpassword.html',
templateUrl: 'modules/pages/templates/forgotpassword.html',
controller: 'ForgotPasswordController as forgot'
})
The most important is replacement of the templateURL with templateUrl. Javascript (and UI-Router) is case sensitive.
We also do not need define url for parent... it could be just child state definition
Finally, we must be sure, that our parent contains some target ui-view="" where child states will be placed. E.g. this is the plunker pages.html:
<div>
<h3>pages</h3>
<hr />
<div ui-view=""></div>
</div>
These links will then work as expected:
//href
<a href="#/signin">
<a href="#/forgotpassword">
//ui-sref
<a ui-sref="pages.signin">
<a ui-sref="pages.forgotpassword">
We can leave the parent url:
$stateProvider.state('pages', {
abstract: true,
url: '/pages',
...
but the href links for child states must contain the parent url as well:
<a href="#/pages/signin">
<a href="#/pages/forgotpassword">
Check it here in action
You need to prefix the state url with the url of the parent state. So the correct url that you need open with the browser should be: #/pages/forgotpassword
Check the doc URL Routing for Nested States