I am using ng-view to include AngularJS partial views, and I want to update the page title and h1 header tags based on the included view. These are out of scope of the parti
When I had to solve this, I couldn't place the ng-app
on the page's html
tag, so I solved it with a service:
angular.module('myapp.common').factory('pageInfo', function ($document) {
// Public API
return {
// Set page <title> tag. Both parameters are optional.
setTitle: function (title, hideTextLogo) {
var defaultTitle = "My App - and my app's cool tagline";
var newTitle = (title ? title : defaultTitle) + (hideTextLogo ? '' : ' - My App')
$document[0].title = newTitle;
}
};
});
Thanks to tosh shimayama for his solution.
I thought it was not so clean to put a service straight into the $scope
, so here's my slight variation on that: http://plnkr.co/edit/QJbuZZnZEDOBcYrJXWWs
The controller (that in original answer seemed to me a little bit too dumb) creates an ActionBar object, and this one is stuffed into $scope.
The object is responsible for actually querying the service. It also hides from the $scope the call to set the template URL, which instead is available to other controllers to set the URL.
A clean way that allow dynamically setting title or meta description. In example I use ui-router but you can use ngRoute in same way.
var myApp = angular.module('myApp', ['ui.router'])
myApp.config(
['$stateProvider', function($stateProvider) {
$stateProvider.state('product', {
url: '/product/{id}',
templateUrl: 'views/product.html',
resolve: {
meta: ['$rootScope', '$stateParams', function ($rootScope, $stateParams) {
var title = "Product " + $stateParams.id,
description = "Product " + $stateParams.id;
$rootScope.meta = {title: title, description: description};
}]
// Or using server side title and description
meta: ['$rootScope', '$stateParams', '$http', function ($rootScope, $stateParams, $http) {
return $http({method: 'GET', url: 'api/product/ + $stateParams.id'})
.then (function (product) {
$rootScope.meta = {title: product.title, description: product.description};
});
}]
}
controller: 'ProductController'
});
}]);
HTML:
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<title ng-bind="meta.title + ' | My App'">myApp</title>
...
The better and dynamic solution I have found is to use $watch to trace the variable changes and then update the title.
Alternatively, if you are using ui-router:
index.html
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<title ng-bind="$state.current.data.title || 'App'">App</title>
Routing
$stateProvider
.state('home', {
url: '/',
templateUrl: 'views/home.html',
data: {
title: 'Welcome Home.'
}
}
If you don't have control over title element (like asp.net web form) here is some thing you can use
var app = angular.module("myApp")
.config(function ($routeProvider) {
$routeProvider.when('/', {
title: 'My Page Title',
controller: 'MyController',
templateUrl: 'view/myView.html'
})
.otherwise({ redirectTo: '/' });
})
.run(function ($rootScope) {
$rootScope.$on("$routeChangeSuccess", function (event, currentRoute, previousRoute) {
document.title = currentRoute.title;
});
});