When I implemented in my code mechanism to change url's query in background (using $location.search), it caused disappearing all tooltips which have option tooltip-append-to-body, at the moment of changing url value. I need tooltip-append-to-body attribute because of another reasons (the simplest solution is to remove it but that's not the solution for me).
My code looks like this:
js:
angular.module('mapp', ['ui.router', 'ui.bootstrap'])
config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.when('', '/');
$stateProvider
.state('home', {
url: '/',
reloadOnSearch: false,
templateUrl: 'home.html'
});
}
])
.controller('myCtrl', ['$scope', '$timeout', '$location',function($scope, $timeout, $location) {
var value = 0;
var runTimeout = function() {
$timeout(function() {
$location.search('start', value++);
runTimeout();
}, 500);
};
runTimeout();
}]);
index.html:
<body ng-app="mapp" ng-controller="myCtrl" style="">
<ui-view></ui-view>
</body>
home.html:
tooltip
Here you have plunker: http://plnkr.co/edit/DkmcSMGmYAowbI4rNQ6W?p=preview.
Related
I keep seeing examples on this but I don't know what I am doing wrong.
I load an item and its content into ng-view. When I refresh the page, it disappears. I have passed a parameter to the URL of the state and I am lost what to do next.
People have talked about $stateParams which I can log from my controller and I can see that item with id: 3 has been selected.
How do I keep the view populated with this item even on refresh? An example with my code would be greatly appreciated.
var app = angular.module('myApp', ['ngRoute', 'ui.router']);
app.config(['$stateProvider', '$locationProvider', '$urlRouterProvider', '$routeProvider', function($stateProvider, $locationProvider, $urlRouterProvider, $routeProvider) {
$urlRouterProvider
.otherwise('/patents');
$stateProvider
.state("patents", {
url: "/patents",
templateUrl: "templates/patents/list/list-patents.htm",
controller: "patentListCtrl",
})
.state("patents.item", {
url: "/:id",
templateUrl: function() {
//THIS IS WHERE I AM NOT SURE HOW TO PASS THE URL THE ID
},
controller: "patentItemCtrl"
})
}]);
app.controller('patentItemCtrl', ['$scope', 'patentTabService','$stateParams', '$state', '$routeParams', function($scope, patentTabFactory, $stateParams, $routeParams){
console.log($stateParams.id)
}])
You should be able to to retrieve the required data by making a call your data service and then assign to your view. In your case call patentTabService to get patent with the id and then load that patent object into your view. For example, note I am assuming you already have some way to get a patent by id in your service:
app.controller('patentItemCtrl', ['$scope', 'patentTabService','$stateParams', '$state', '$routeParams', function($scope, patentTabFactory, $stateParams, $routeParams){
$scope.patent = {};
if (Number.isInteger($stateParams.id) ){
$scope.patent = patentTabFactory.getPatent($stateParams.id);
}
console.log($stateParams.id)
}])
I'm working on a POC for work and I can't find whatever stupid mistake is hiding here. I have a bare-bones/basic angular app, using ui-router. Plunker can be found here.
In the chrome console I can see my app.module is being created, however the login page never appears. This is a very, very basic app so I figure it must be something simple I'm missing. Any suggestions? Below is a quick sample:
config.js
(function() {
'use strict'
var app = angular.module('app.core');
app.config(AppRouter);
AppRouter.$inject = ['$stateProvider', '$urlRouterProvider'];
function AppRouter($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('login');
$stateProvider
.state('/', {
templateUrl: 'login.html',
controller: 'LoginController',
controllerAs: 'vm',
})
.state('login', {
templateUrl: 'login.html',
controller: 'LoginController',
controllerAs: 'vm',
});
}
})();
login.controller.js
(function() {
'use strict';
var app = angular.module('app.login');
app.controller('LoginController', LoginController);
LoginController.$inject = ['$location', '$filter', '$window', '$rootScope'];
function LoginController($location, $filter, $window, $rootScope) {
var init = function() {
console.log('here');
};
init();
}
})();
app.module.js
(function() {
var app = angular.module('app', ['app.core', 'app.login']);
})();
login.module.js
(function(){
'use strict'
var app = angular.module('app.login', ['app.core']);
})();
core.module.js
(function(){
'use strict'
var app = angular.module('app.core', ['ui.router']);
})();
After few changes it worked for me (see forked plunk: https://plnkr.co/edit/D5AL8DTnqYI2g23wjE7W?p=preview):
You forgot to load AngularJS (between <head></head).
You forgot to add ng-app, I add it on body.
And I made some changes in config.js:
function AppRouter($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/login');
$stateProvider
.state('/', {
templateUrl: 'login.html',
controller: 'LoginController',
controllerAs: 'vm',
})
.state('login', {
url: '/login',
templateUrl: 'login.html',
controller: 'LoginController',
controllerAs: 'vm',
});
}
I add url to login state, and I made changes to otherwise function: I changed login to /login cause it needs URL, not state name.
I think you overconfigured you app a little bit (too much modules), and it makes it hard to read for me, but it's only my opinion and to be frankly, maybe it's only because I don't use modules very frequently. Try to add this changes to your Plunk and please write if it won't work, casue I could accidentally skip something.
If its index then add else remove class in body tag
app.js
angular.module('app', [
'ui.router',
'ngAnimate'
])
.config(
[ '$stateProvider', '$urlRouterProvider',
function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider
.otherwise('/');
$stateProvider
.state("app", {
url: "",
templateUrl: 'tmpl/app.html'
})
.state('app.about', {
url: '/about',
templateUrl: 'tmpl/aboutus.html'
})
.state('app.result', {
url: '/result',
templateUrl: 'tmpl/search_result.html'
})
}
]
);
index.html
<body class="home" ng-class="" >
Add class if its Home page abc.com/ else remove the added class, ex: abc.com/#/about
Thanks in advance
Kanagan
There are many options could create a controller for the body to handle this or do this with a directive or service. The easiest option would be to use $rootScope.
angular.module('app', [
'ui.router',
'ngAnimate'
])
.run(['$rootScope',function($rootScope){
$rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams){
//console.log(toState);
$rootScope.home = (toState.name == 'app');
});
}])
.config(['$stateProvider', '$urlRouterProvider', function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider
.otherwise('/');
$stateProvider
.state("app", {
url: "",
templateUrl: 'tmpl/app.html'
})
.state('app.about', {
url: '/about',
templateUrl: 'tmpl/aboutus.html'
})
.state('app.result', {
url: '/result',
templateUrl: 'tmpl/search_result.html'
})
}]);
then in the html...
<body class="home" ng-class="{'my-home-class':$root.home}">
I didn't test this. If it doesn't work do a console.log on toState and see what the value is on different pages and adjust the code as needed.
UPDATE
I created a plunker with a functional example. I'm not sure what is in your app.html, but the way you have this set up I'd advise adding another state for app.home which I created in my example.
I have markup that has the following and then I have different sections of the app defined in different files. The problem I am running into is that the controllers that are on the main app page on load causes each of the nested controllers to run more than once. Any states that I change to with a click of the button are fine but these fire off 2-3 times each.
<html ng-app="myApp">
<body ng-controller="myController">
<div ng-controller="dashController">
<div ng-controller="listController">
</div>
</div>
</body>
</html>
My App.js
var myApp = angular.module('myApp', [
'user.profile',
'myApp.controllers',
'myApp.directives',
'ngCookies',
'ngAutocomplete',
'ui.router'
]).config(function($stateProvider, $urlRouterProvider, $locationProvider, $interpolateProvider) {
$interpolateProvider.startSymbol('{[{').endSymbol('}]}');
$urlRouterProvider.otherwise('/');
$stateProvider.
state('app', {
url: '/app',
templateUrl: '/views/homepage',
controller: 'MyCtrl1'
});
$locationProvider.html5Mode(true);
});
myApp.controllers
angular.module('myApp.controllers', ['ui.router','ngCookies']).
controller('myController', function ($scope, $http,$cookies) {
$scope.message = 'nothing to see here, move along';
if ($cookies.userdata) {
$cookies.userdata = $cookies.userdata.replace("j:", "");
console.log($cookies);
}
});
user.profile.js
angular.module('user.profile', [
'user.controllers',
'ngAnimate',
'ngCookies',
'ngResource',
'ngSanitize',
'nouislider',
'ui.router',
'ui.bootstrap',
'ngLinkedIn'
])
.config(function($stateProvider, $urlRouterProvider, $locationProvider,$interpolateProvider, $linkedInProvider) {
$interpolateProvider.startSymbol('{[{').endSymbol('}]}');
$linkedInProvider.set('appKey', '753pos06f998t3')
.set('scope', 'r_fullprofile');
//.set('authorize', true);
$locationProvider.html5Mode(true);
$stateProvider
.state('userDashboard', {
controller: 'dashController'
})
.state('userList', {
views : {
'popup' : {templateUrl: '/views/app/user/list/userList'}
},
controller: 'listController'
});
});
user.controllers.js
angular.module('user.controllers', ['ui.router', 'ngAutocomplete', 'nouislider', 'ui.bootstrap', 'ngCookies', 'ngLinkedIn', 'angularFileUpload','cgPrompt'])
.directive('onLastRepeat', function () {
return function (scope, element, attrs) {
if (scope.$last) setTimeout(function () {
scope.$emit('onRepeatLast', element, attrs);
}, 1);
};
}).
controller('dashController', function ($scope, $state, $modal, $log, $http, $cookies) {
$scope.user = [];
}).
controller('listController', function ($scope, $http, $cookies) {
});
My app also doesn't initialize unless I run angular.bootstrap(document, ["myApp"]);
I don't think it is having the controller defined in the $stateProvider and the DOM... if I remove from the DOM none of the ng-clicks work even after the controller fires... also I have an ng-click that changes the state and it's controller is defined in the stateProvider and in the DOM and it does not fire twice... what is does is kick off the two other controllers again first before proceeding with it's action though.
The issue is that you are defining your controllers with the routeProvider / stateProvider ie:
$stateProvider.state('userDashboard', {
controller: 'dashController'
})
.state('userList', {
views : {
'popup' : {templateUrl: '/views/app/user/list/userList'}
},
controller: 'listController'
});
an you are redifining them in the DOM using
<div ng-controller="dashController">
remove one or the other but don't use the two at the same time, I'd suggest to remove the one declared in the DOM, ng-controller="dashController"
cheers
I am having a lot of trouble understanding how stateParams are supposed to work. Everywhere I look suggests that this should pass an item_id of 456 when I travel to the URL /#/manage/456, but instead $stateParams is an empty object. Furthermore, in the $state object that is passed to MainCtrl, I can access all of the parameters by using $state.params, however this seems to be undesirable and hackish.
angular
.module('router',['ui.router'])
.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider)
{
$stateProvider
.state('manage',
{
url: '/manage',
templateUrl: '/templates/main.html',
controller: 'MainCtrl'
})
.state('manage.item_id',
{
url: '/:item_id',
templateUrl: '/templates/main.html',
controller: 'MainCtrl'
})
}])
.controller('MainCtrl', ['$scope', '$stateParams', '$state', function($scope, $stateParams, $state)
{
// empty object
console.log('$stateParams: ', $stateParams);
// shows the variables i want
console.log('$state.params: ', $state.params);
}])
What you're trying to do should work fine, see this JSFiddle: http://jsfiddle.net/ahchurch/gf7Fa/14/
<script type="text/ng-template" id="item.tpl.html">
embeded item template
</script>
<script type="text/ng-template" id="main.tpl.html">
<ul>
<li>change route</li>
</ul>
<div ui-view></div>
</script>
<div ui-view></div>
angular.module('myApp',['ui.router'])
.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider)
{
$urlRouterProvider.otherwise("/manage");
$stateProvider
.state('manage',
{
url: '/manage',
templateUrl: 'main.tpl.html',
controller: 'MainCtrl'
})
.state('manage.item_id',
{
url: '/:item_id',
templateUrl:'item.tpl.html',
controller: 'MainCtrl'
})
}])
.controller('mainController', function(){})
.controller('MainCtrl', ['$scope', '$stateParams', '$state', function($scope, $stateParams, $state)
{
// empty object
console.log("main controller");
console.log($stateParams);
}]);
One thing I noticed is that your template is the same file for both states, so you may just be seeing the initialization of the "manage" state, and never seeing the "manage.item_id" state.