我正在迁移基于AngularJS的应用程序以使用ui-router而不是内置路由。我把它配置如下所示
.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/home');
$stateProvider
.state('home', {
url: '/home',
templateUrl : 'views/home.html',
data : { pageTitle: 'Home' }
})
.state('about', {
url: '/about',
templateUrl : 'views/about.html',
data : { pageTitle: 'About' }
})
});
如何使用pageTitle变量动态设置页面标题?使用内置路由,我可以做
$rootScope.$on("$routeChangeSuccess", function(currentRoute, previousRoute){
$rootScope.pageTitle = $route.current.data.pageTitle;
});
然后在HTML中绑定变量,如下所示
<title ng-bind="$root.pageTitle"></title>
是否有类似的事件我可以使用ui-router挂钩?我注意到有&#39; onEnter&#39;和&#39; onExit&#39;函数,但它们似乎与每个状态绑定,并要求我重复代码为每个状态设置$ rootScope变量。
答案 0 :(得分:106)
使用$stateChangeSuccess
。
你可以把它放在一个指令中:
app.directive('updateTitle', ['$rootScope', '$timeout',
function($rootScope, $timeout) {
return {
link: function(scope, element) {
var listener = function(event, toState) {
var title = 'Default Title';
if (toState.data && toState.data.pageTitle) title = toState.data.pageTitle;
$timeout(function() {
element.text(title);
}, 0, false);
};
$rootScope.$on('$stateChangeSuccess', listener);
}
};
}
]);
和
<title update-title></title>
演示: http://run.plnkr.co/8tqvzlCw62Tl7t4j/#/home
代码: http://plnkr.co/edit/XO6RyBPURQFPodoFdYgX?p=preview
即使使用$stateChangeSuccess
,历史记录仍然需要$timeout
,至少在我自己测试过时。
编辑:2014年11月24日 - 陈述性方法:
app.directive('title', ['$rootScope', '$timeout',
function($rootScope, $timeout) {
return {
link: function() {
var listener = function(event, toState) {
$timeout(function() {
$rootScope.title = (toState.data && toState.data.pageTitle)
? toState.data.pageTitle
: 'Default title';
});
};
$rootScope.$on('$stateChangeSuccess', listener);
}
};
}
]);
和
<title>{{title}}</title>
答案 1 :(得分:90)
通过结合大部分答案,还有另一种方法可以做到这一点。我知道这已经回答了,但我想展示一下用ui-router动态更改页面标题的方式。
如果您查看ui-router sample app,他们会使用角度.run块将$ state变量添加到$ rootScope。
// It's very handy to add references to $state and $stateParams to the $rootScope
// so that you can access them from any scope within your applications.
// For example, <li ng-class="{ active: $state.includes('contacts.list') }">
// will set the <li> to active whenever 'contacts.list' or one of its
// decendents is active.
.run([ '$rootScope', '$state', '$stateParams',
function ($rootScope, $state, $stateParams) {
$rootScope.$state = $state;
$rootScope.$stateParams = $stateParams;
}])
通过此定义,您可以使用已发布的内容轻松动态更新页面标题,但已修改为使用已定义的状态:
以相同的方式设置状态:
.state('home', {
url: '/home',
templateUrl : 'views/home.html',
data : { pageTitle: 'Home' }
})
但是稍微编辑一下html ......
<title ng-bind="$state.current.data.pageTitle"></title>
我不能说这比以前的答案更好......但我更容易理解和实施。希望这有助于某人!
答案 2 :(得分:17)
angular-ui-router-title插件可以根据当前状态轻松将页面标题更新为静态或动态值。它也适用于浏览器历史记录。
答案 3 :(得分:13)
$stateChangeSuccess
现在为deprecated in UI-Router 1.x,默认情况下已停用。您现在需要使用新的$transition
服务。
一旦了解$transition
的工作原理,解决方案就不会太困难。我从@troig那里得到了一些help来理解这一切。以下是我为更新标题而提出的建议。
将它放在Angular 1.6应用程序中。 请注意,我使用的是ECMAScript 6语法;如果你不是,你需要,例如将let
更改为var
。
.run(function($transitions, $window) {
$transitions.onSuccess({}, (transition) => {
let title = transition.to().title;
if (title) {
if (title instanceof Function) {
title = title.call(transition.to(), transition.params());
}
$window.document.title = title;
}
});
然后只需在您的州添加title
字符串:
$stateProvider.state({
name: "foo",
url: "/foo",
template: "<foo-widget layout='row'/>",
title: "Foo Page""
});
这将使&#34; Foo Page&#34;出现在标题中。 (如果一个州没有标题,页面标题将不会更新。如果一个州没有表明一个,那么更新上面的代码以提供默认标题将是一件简单的事。)
该代码还允许您使用title
的函数。用于调用函数的this
将是状态本身,而一个参数将是状态参数,如下例所示:
$stateProvider.state({
name: "bar",
url: "/bar/{code}",
template: "<bar-widget code='{{code}}' layout='row'/>",
title: function(params) {
return `Bar Code ${params.code}`;
}
});
对于显示&#34;条形码123&#34;的网址路径/bar/code/123
作为页面标题。 请注意,我使用ECMAScript 6语法格式化字符串并提取params.code
。
如果有时间的人会把这样的东西放到指令中并发布给每个人使用,那就太好了。
答案 4 :(得分:5)
将$ state附加到$ rootscope以在应用程序的任何位置使用。
app.run(['$rootScope', '$state', '$stateParams',
function ($rootScope, $state, $stateParams) {
// It's very handy to add references to $state and $stateParams to the $rootScope
// so that you can access them from any scope within your applications.For example,
// <li ng-class="{ active: $state.includes('contacts.list') }"> will set the <li>
// to active whenever 'contacts.list' or one of its decendents is active.
$rootScope.$state = $state;
$rootScope.$stateParams = $stateParams;
}
]
)
&#13;
<title ng-bind="$state.current.name + ' - ui-router'">about - ui-router</title>
&#13;
答案 5 :(得分:5)
我发现this way非常简单:
.state('app.staff.client', {
url: '/client/mine',
title: 'My Clients'})
然后在我的HTML中这样:
<h3>{{ $state.current.title }}</h3>
答案 6 :(得分:3)
只需更新window.document.title:
.state('login', {
url: '/login',
templateUrl: "/Login",
controller: "loginCtrl",
onEnter: function($window){$window.document.title = "App Login"; }
})
那样&#39; ng-app&#39;不需要移动到HTML标记,可以保持身体或更低。
答案 7 :(得分:3)
我正在使用ngMeta,这不仅适用于设置页面标题,也适用于描述。它允许您为每个州设置特定的标题/描述,默认为未指定标题/描述时,以及默认标题后缀(即&#39; | MySiteName&#39;)和作者值。
$stateProvider
.state('home', {
url: '/',
templateUrl: 'views/home.html',
controller: 'HomeController',
meta: {
'title': 'Home',
'titleSuffix': ' | MySiteName',
'description': 'This is my home page description lorem ipsum.'
},
})
答案 8 :(得分:2)
你真的很接近你的第一个答案/问题。将您的标题添加为数据对象:
.state('home', {
url: '/home',
templateUrl : 'views/home.html',
data : { pageTitle: 'Home' }
})
在index.html中将数据直接绑定到页面标题:
<title data-ng-bind="$state.current.data.pageTitle + ' - Optional text'">Failsafe text</title>
答案 9 :(得分:1)
为什么不呢:
$window.document.title = 'Title';
更新:完整指令代码
var DIRECTIVE = 'yourPageTitle';
yourPageTitle.$inject = ['$window'];
function yourPageTitle($window: ng.IWindowService): ng.IDirective {
return {
link: (scope, element, attrs) => {
attrs.$observe(DIRECTIVE, (value: string) => {
$window.document.title = value;
});
}
}
}
directive(DIRECTIVE, yourPageTitle);
然后在每个页面中,您只需要包含此指令:
<section
your-page-title="{{'somePage' | translate}}">
答案 10 :(得分:1)
我最终结合了Martin和tasseKATT的答案 - 简单而没有任何与模板相关的东西:
$rootScope.$on("$stateChangeSuccess", function (event, toState) {
$timeout(function () { // Needed to ensure the title is changed *after* the url so that history entries are correct.
$window.document.title = toState.name;
});
});
答案 11 :(得分:0)
如果你使用的是ES6,这很好用:)。
class PageTitle {
constructor($compile, $timeout) {
this.restrict = 'A';
this._$compile = $compile;
this.$timeout = $timeout;
}
compile(element) {
return this.link.bind(this);
}
link(scope, element, attrs, controller) {
let defaultTitle = attrs.pageTitle ? attrs.pageTitle : "My Awesome Sauce Site";
let listener = function(event, toState) {
let title = defaultTitle;
if (toState.data && toState.data.title) title = toState.data.title + ' | ' + title;
$('html head title').text(title);
};
scope.$on('$stateChangeStart', listener);
}
}
export function directiveFactory($compile) {
return new PageTitle($compile);
}
directiveFactory.injections = ['$compile', '$timeout'];
export default PageTitle;
答案 12 :(得分:0)
也许你可以尝试这个指令。
https://github.com/afeiship/angular-dynamic-title
<title dynamic-title>Title</title>
<a href="javascript:;" ui-sref="state1">State1 page</a>
<a href="javascript:;" ui-sref="state2">State2 page</a>
var TestModule = angular.module('TestApp', ['ui.router','nx.widget'])
.config(function ($stateProvider, $urlRouterProvider) {
//
// For any unmatched url, redirect to /state1
$urlRouterProvider.otherwise("/state1");
//
// Now set up the states
$stateProvider
.state('state1', {
url: "/state1",
templateUrl: "partials/state1.html",
data:{
pageTitle:'State1 page title11111'
}
})
.state('state2', {
url: "/state2",
templateUrl: "partials/state2.html",data:{
pageTitle:'State2 page title222222'
}
});
})
.controller('MainCtrl', function ($scope) {
console.log('initial ctrl!');
});
答案 13 :(得分:0)
对于更新的UI-Router 1.0.0+版本, (https://ui-router.github.io/guide/ng1/migrate-to-1_0)
请参阅以下代码
app.directive('pageTitle', [
'$rootScope',
'$timeout',
'$transitions',
function($rootScope, $timeout,$transitions) {
return {
restrict: 'A',
link: function() {
var listener = function($transitions) {
var default_title = "DEFAULT_TITLE";
$timeout(function() {
$rootScope.page_title = ($transitions.$to().data && $transitions.$to().data.pageTitle)
? default_title + ' - ' + $transitions.$to().data.pageTitle : default_title;
});
};
$transitions.onSuccess({ }, listener);
}
}
}
])
&#13;
将以下内容添加到index.html:
<title page-title ng-bind="page_title"></title>
&#13;