So I am using ui-view to route me to a partial.
//route.provider.js
(function() {
'use strict';
angular
.module('app')
.provider('RouteService', RouteService);
RouteService.$inject = ['$stateProvider', '$urlRouterProvider'];
function RouteService ($stateProvider, $urlRouterProvider) {
var service = {};
this.$get = function() { return service; };
this.initialize = function() {
$urlRouterProvider.otherwise('/login');
$stateProvider
.state('home', {
url: '/home',
controller: 'HomeController',
templateUrl: 'home/home.view.html',
controllerAs: 'viewModel'
})
.state('login', {
url: '/login',
controller: 'LoginController',
templateUrl: 'login/login.view.html',
controllerAs: 'viewModel'
})
//TODO Impliment the following partial pages...
.state('gensim', {
url: '/gensim',
templateUrl: 'general-simulation/simulation.view.html',
controller: 'TabsController',
controllerAs: 'tabs'
})
<...more routes...>
}
}
})();
The issue I am having is once it routes to
// general-simulation/simulation.view.html
I'd like it to use a custom directive to insert more html into the page.
Inside simulation.view.html I have this.
<div class="container">
<div class="row center">
<div class="col-xs-12">
<h1>General Simulation</h1>
<gs-tabs><h1>TEST!!!!</h1></gs-tabs>
</div>
</div>
</div>
The directive is constructed in
// tabs.directives.js
(function(){
'use strict';
angular
.module('app')
.directive('gsTabs', gsTabs);
function gsTabs () {
return {
restrict: "E",
templateURL: 'tabs.view.html'
};
}
})();
Finally, my tabs.view.html looks like this.
<h1>YOU HAVE ENTERED TABS PARTIAL</h1>
When I navigate to the page that displays simulation.view all I can see is:
General Simulation
TEST!!!!
So what am I doing wrong here. I checked for camelCasing and the page is not showing in errors. Any help would be greatly appreciated!
Update:
I viewed the network calls in chrome's dev tools.
simulation.view.html is being loaded but tabs.view.html isn't.
Request URL:http://sdc-stagt01/AngularJS/general-simulation/simulation.view.html
Request Method:GET
Status Code:200 OK
Remote Address:10.19.8.96:80
The file substructure is:
/general-simulation/tabs/tabs.controller.js
/general-simulation/tabs/tabs.directives.js
/general-simulation/tabs/tabs.view.html
/general-simulation/simulation.view.html
putting comment as answer
change templateURL to templateUrl
So entre's comment was a big help. That got chrome dev to start spitting out errors.
charlietfl Was on the right track with mentioning my file structure as well. I needed to change my directive to look like this:
templateUrl: 'general-simulation/tabs/tabs.view.html'
Thank you!
You have a typo here. templateUrl not templateURL
function gsTabs () {
return {
restrict: "E",
templateURL: 'tabs.view.html' // change this to templateUrl
};
}
Related
I am trying to capture a route to be something like
www.mysite.com/#name=ted&location=ca
I am using stateprovider and I setup as follow:
$stateProvider
.state('home', {
url: '/#name',
controller: function () {
alert('here')
do stuff...
}
})
but for some reason, alert never trigger.
Can someone help me about it? Thanks a lot!
To get params via query string you can use try:
$stateProvider
.state('home', {
url: '/?name&location',
controller: function () {
alert('here')
do stuff...
}
})
# will be there if HTML5 mode is disabled.
var app= angular.module('appName', []);
app.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/home', {
templateUrl: 'templates/home.html',
controller: 'AddOrderController'
}).
when('/contact', {
templateUrl: 'templates/contact.html',
controller: 'ShowOrdersController'
}).
otherwise({
redirectTo: '/home'
});
}]);
Try This Is Example Of Navigation Using With route Providers .
When using ui.router, all routes need a template, include that in your state, remove the # sign from the URL and it should work
I am new to angular and ionic, my app information goes like this: I have a splash screen on which I have my login page,followed by home screen.Now the problem is if the user has logged in once,then whenever the app is closed and opened again it shows the login screen,instead it should show home screen. How do I achieve that. I have tried many solutions, but none of them worked. Kindly help.
var kit = angular.module('starter', ['ionic','ionic.service.core', 'ngCordova']);
kit.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('start', {
url: '/',
templateUrl: 'templates/start.html',
controller: 'StartController'
})
.state('home', {
url: '/home',
templateUrl: 'templates/home.html',
controller: 'HomeController'
})
.state('scrollView', {
url: '/scroll',
templateUrl: 'templates/ScrollEx.html',
controller: 'ScrollExController'
})
.state('check', {
url: '/check',
templateUrl: 'templates/check.html',
controller: 'CheckController'
})
$urlRouterProvider.otherwise('/');
});
In your login page's controller, I assume this is StartController, you can use something like:
// Note you need $location for navigation here:
app.controller('StartController', ['$rootScope', '$scope', '$location', /*...*/
function ($rootScope, $scope, $location /*...*/) {
// Test condition, just an example:
if (sessionStorage.user.id) {
$location.path('/home');
}
// Controller code goes here
});
This is assuming you condition is sessionStorage.user.id.
Angular's $location will handle router navigation elegantly for you.
Source: AngularJS: $location
Original Question
I'm developing a mobile app using the Ionic Framework and AngularJS and I am having issues with controllers not reloading once they have been initialised.
One of the state transitions (from 'app.postbox-details' to 'app.audit-questions') should pass a parameter to the 'app.audit-questions' controller but this controller does not update itself with the new parameter because it isn't reloading.
Code Example
app.js file - config
angular.module('sf-maintenance', ['ionic', 'starter.controllers', 'starter.services', 'ngCordova'])
.config(function ($stateProvider, $urlRouterProvider, $httpProvider) {
$stateProvider
.state('home', {
url: '/home',
templateUrl: 'templates/home.html',
controller: 'HomeCtrl',
})
.state('app', { //app state being the side-menu
url: '/app',
abstract: true, //means that this state will never be activated directly, users will always go to a child state instead.
templateUrl: 'templates/side-menu.html',
controller: 'MenuCtrl'
})
.state('app.postbox-details', {
url: '/postbox-details',
views: {
'menuContent': {
templateUrl: 'templates/postbox-details.html',
controller: 'PostboxDetailsCtrl'
}
}
})
.state('app.audit-questions', {
url: '/audit-questions/:postboxGuid',
views: {
'menuContent': {
templateUrl: 'templates/audit-questions.html',
controller: 'AuditCtrl'
}
}
})
$urlRouterProvider.otherwise('/home');
});
controller.js file (left out the code that isn't relevant)
angular.module('starter.controllers', [])
.controller('HomeCtrl', function ($scope) {
})
.controller('MenuCtrl', function ($scope) {
})
.controller('PostboxDetailsCtrl', function ($scope, $ionicLoading, $ionicPopup, $cordovaBarcodeScanner, $state, DataService) {
$scope.postboxGuid = DataService.getNewGUID();
//Rest of the controller functions are below
})
.controller('AuditCtrl', function ($scope, $ionicSlideBoxDelegate, $stateParams, DataService) {
$scope.auditDetails = {
postboxGuid: $stateParams.postboxGuid
};
});
View - navigation code
The view code to perform the navigations all use <a> tags:
From the home view to the postbox-details view: <a class="button button-block button-dark icon-right ion-chevron-right" href="#/app/postbox-details">New inspection</a>
From the postbox-details view to audit-questions view: <a class="button button-block button-dark icon-right ion-chevron-right" ng-click="saveFormData()"
ng-href="#/app/audit-questions/{{postboxGuid}}">New audit</a>
So does anybody know how to get controllers to reload once it has been initialised or if I am going about this problem the wrong way could you guide me to a method that will work?
Updated Information
I recently saw a related question and the response by #Radim Köhler pointed to the answer in this question which provides good information on why it may not be a good idea to use cache:false on a view because of performance.
I thought I would share this because in some situations you may benefit more performance-wise by using one of Ionic's built-in view life cycle events to run code without having to disable the view from being cached.
Views are standard cached in ionic. The caching can configured in the view or stateprovider.
http://ionicframework.com/docs/api/directive/ionNavView/
I'd like to load a view with template/controller configured in a ui-router state, but the controller doesn't seem to get loaded, no matter what I try, without any error messages.
module App {
var dependencies = [
"ui.router",
Controllers
]
function configuration($stateProvider: ng.ui.IStateProvider) {
$stateProvider
.state("test", {
url: "/test",
views: {
"": { templateUrl: "parentView.html" },
"testPartial#" : {
templateUrl: "partial.html",
controller: <--- see below
...
}
...
}
What I tried:
controller: Controllers.TestController
controller: App.Controllers.TestController
controller: "App.Controllers.TestController"
controller: "App.Controllers.ITestController" (interface)
However, if I declare ng-controller="App.Controllers.TestController as vm" on my template, everything works flawlessly.
Given what works on ng-controller, controller: "App.Controllers.TestController" is guaranteed to work.
The isse is with the as vm portion being missing. You can overcome that by putting the controller on the scope: https://youtube.com/watch?v=WdtVn_8K17E&hd=1
I am trying to do what was essentially answered here Unable to open bootstrap modal window as a route
Yet my solution just will not work. I get an error
Error: [$injector:unpr] Unknown provider: $modalProvider <- $modal
My app has the ui.bootstrap module injected - here is my application config
var app = angular.module('app', ['ui.router', 'ui.bootstrap','ui.bootstrap.tpls', 'app.filters', 'app.services', 'app.directives', 'app.controllers'])
// Gets executed during the provider registrations and configuration phase. Only providers and constants can be
// injected here. This is to prevent accidental instantiation of services before they have been fully configured.
.config(['$stateProvider', '$locationProvider', function ($stateProvider, $locationProvider) {
// UI States, URL Routing & Mapping. For more info see: https://github.com/angular-ui/ui-router
// ------------------------------------------------------------------------------------------------------------
$stateProvider
.state('home', {
url: '/',
templateUrl: '/views/index',
controller: 'HomeCtrl'
})
.state('transactions', {
url: '/transactions',
templateUrl: '/views/transactions',
controller: 'TransactionsCtrl'
})
.state('login', {
url: "/login",
templateUrl: '/views/login',
controller: 'LoginCtrl'
})
.state('otherwise', {
url: '*path',
templateUrl: '/views/404',
controller: 'Error404Ctrl'
});
$locationProvider.html5Mode(true);
}])
I have reduced my controller to the following:
appControllers.controller('LoginCtrl', ['$scope', '$modal', function($scope, $modal) {
$modal.open({templateUrl:'modal.html'});
}]);
Ultimately, what I am hoping to achieve is when login is required not actually GO to the login page, but bring up a dialog.
I have also tried using the onEnter function in the ui-router state method. Couldn't get this working either.
Any ideas?
UPDATE
Ok - so as it turns out, having both ui-bootstrap.js AND ui-bootstrap-tpls breaks this - After reading the docs I thought you needed the templates to work WITH the ui-bootstrap. though it seems all the plunkers only load in the ..tpls file - once I removed the ui-bootstrap file my modal works...Am i blind? or doesn't it not really say which one you need in the docs on github? -
Now i just need to figure out how to prevent my url from actually going to /login, rather than just show the modal :)
update 2
Ok, so by calling $state.go('login') in a service does this for me.
Hi I had a hard time getting through the similar problem.
However, I was able to resolve it.
This is what you would probably need.
app.config(function($stateProvider) {
$stateProvider.state("managerState", {
url: "/ManagerRecord",
controller: "myController",
templateUrl: 'index.html'
})
.state("employeeState", {
url: "empRecords",
parent: "managerState",
params: {
empId: 0
},
onEnter: [
"$modal",
function($modal) {
$modal.open({
controller: "EmpDetailsController",
controllerAs: "empDetails",
templateUrl: 'empDetails.html',
size: 'sm'
}).result.finally(function() {
$stateProvider.go('^');
});
}
]
});
});
Click here for plunker. Hope it helps.
I'm working on something similar and this is my solution.
HTML code
<a ui-sref="home.modal({path: 'login'})" class="btn btn-default" ng-click="openModal()">Login</a>
State configuration
$stateProvider
// assuming we want to open the modal on home page
.state('home', {
url: '/',
templateUrl: '/views/index',
controller: 'HomeCtrl'
})
// create a nested state
.state('home.modal', {
url: ':path/'
});
Home controller
//... other code
$scope.openModal = function(){
$modal.open({
templateUrl: 'path/to/page.html',
resolve: {
newPath: function(){
return 'home'
},
oldPath: function(){
return 'home.modal'
}
},
controller: 'ModalInstanceController'
});
};
//... other code
Finally, the modal instance controller.
This controller synchronizes the modal events (open/close) with URL path changes.
angular.module("app").controller('ModalInstanceController', function($scope, $modalInstance, $state, newPath, oldPath) {
$modalInstance.opened.then(function(){
$state.go(newPath);
});
$modalInstance.result.then(null,function(){
$state.go(oldPath);
});
$scope.$on('$stateChangeSuccess', function () {
if($state.current.name != newPath){
$modalInstance.dismiss('cancel')
}
});
});
You may create a state with the same templateUrl and controller as your page where you want to show the modal, adding params object to it
$stateProvider
.state('root.start-page', {
url: '/',
templateUrl: 'App/src/pages/start-page/start-page.html',
controller: 'StartPageCtrl'
})
.state('root.login', {
url: '/login',
templateUrl: 'App/src/pages/start-page/start-page.html',
controller: 'StartPageCtrl',
params: {
openLoginModal: true
}
})
And in controller of the page, use this parameter to open the modal
.controller("StartPageCtrl", function($scope, $stateParams) {
if ($stateParams.openLoginModal) {
$scope.openLoginModal();
}
I found a handy hint to get this working. There are probably caveats, but it works for me. You can pass a result still but I have no need for one.
Using finally instead of the then promise resolve sorted this for me. I also had to store the previous state on rootScope so we knew what to go back to.
Save previous state to $rootScope
$rootScope.previousState = 'home';
$rootScope.$on('$stateChangeSuccess', function(ev, to, toParams, from, fromParams){
$rootScope.previousState = from.name;
})
State using onEnter
$stateProvider.state('contact', {
url: '/contact',
onEnter: function ($state, $modal, $rootScope){
$modal.open({
templateUrl: 'views/contact.html',
controller: 'ContactCtrl'
}).result.finally(function(){
$state.go($rootScope.previousState);
})
}
});