我使用ng-view来包括AngularJS的部分视图,我想根据所包含的视图更新页面标题和h1头标签。这些超出了局部视图控制器的范围,所以我不知道如何将它们绑定到控制器中的数据集。
如果是ASP。NET MVC,你可以使用@ViewBag来做这个,但我不知道在AngularJS中等价的。我已经搜索了共享服务,事件等,但仍然不能让它工作。任何方式修改我的例子,使其工作将非常感激。
我的HTML:
<html data-ng-app="myModule">
<head>
<!-- include js files -->
<title><!-- should changed when ng-view changes --></title>
</head>
<body>
<h1><!-- should changed when ng-view changes --></h1>
<div data-ng-view></div>
</body>
</html>
我的JavaScript:
var myModule = angular.module('myModule', []);
myModule.config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/test1', {templateUrl: 'test1.html', controller: Test1Ctrl}).
when('/test2', {templateUrl: 'test2.html', controller: Test2Ctrl}).
otherwise({redirectTo: '/test1'});
}]);
function Test1Ctrl($scope, $http) { $scope.header = "Test 1";
/* ^ how can I put this in title and h1 */ }
function Test2Ctrl($scope, $http) { $scope.header = "Test 2"; }
我刚刚发现了一个很好的方法来设置你的页面标题,如果你使用路由:
JavaScript:
var myApp = angular.module('myApp', ['ngResource'])
myApp.config(
['$routeProvider', function($routeProvider) {
$routeProvider.when('/', {
title: 'Home',
templateUrl: '/Assets/Views/Home.html',
controller: 'HomeController'
});
$routeProvider.when('/Product/:id', {
title: 'Product',
templateUrl: '/Assets/Views/Product.html',
controller: 'ProductController'
});
}]);
myApp.run(['$rootScope', function($rootScope) {
$rootScope.$on('$routeChangeSuccess', function (event, current, previous) {
$rootScope.title = current.$$route.title;
});
}]);
HTML:
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<title ng-bind="'myApp — ' + title">myApp</title>
...
编辑:使用ng-bind属性代替{{}},这样它们在加载时不会显示
虽然其他人可能有更好的方法,但我能够在我的控制器中使用$rootScope,因为我的每个视图/模板都有一个不同的控制器。您需要在每个控制器中注入$rootScope。虽然这可能不太理想,但它对我来说很有用,所以我想我应该把它传下去。如果检查页面,它会将ng-binding添加到title标签中。
例控制器:
myapp.controller('loginPage', ['$scope', '$rootScope', function ($scope, $rootScope) {
// Dynamic Page Title and Description
$rootScope.pageTitle = 'Login to Vote';
$rootScope.pageDescription = 'This page requires you to login';
}]);
示例Index.html头文件:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<meta name="description" content="{{pageDescription}}">
<meta name="author" content="">
<link rel="shortcut icon" href="../../assets/ico/favicon.ico">
<base href="/">
<title>{{pageTitle}}</title>
你也可以将pageTitle和pageDescription设置为动态值,例如从REST调用返回数据:
$scope.article = restCallSingleArticle.get({ articleID: $routeParams.articleID }, function() {
// Dynamic Page Title and Description
$rootScope.pageTitle = $scope.article.articletitle;
$rootScope.pageDescription = $scope.article.articledescription;
});
同样,其他人可能对如何处理这个问题有更好的想法,但由于我使用预渲染,我的需求得到了满足。
在html元素上声明ng-app为头部和主体提供了根作用域。
因此在你的控制器中注入$rootScope并设置一个header属性:
function Test1Ctrl($rootScope, $scope, $http) { $rootScope.header = "Test 1"; }
function Test2Ctrl($rootScope, $scope, $http) { $rootScope.header = "Test 2"; }
在你的页面中:
<title ng-bind="header"></title>
这些答案似乎都不够直观,所以我创建了一个小指令来做这件事。这种方式允许您在页面中声明标题,而通常情况下是这样做的,并允许它是动态的。
angular.module('myModule').directive('pageTitle', function() {
return {
restrict: 'EA',
link: function($scope, $element) {
var el = $element[0];
el.hidden = true; // So the text not actually visible on the page
var text = function() {
return el.innerHTML;
};
var setTitle = function(title) {
document.title = title;
};
$scope.$watch(text, setTitle);
}
};
});
当然,您需要更改模块名以匹配您的模块名。
要使用它,只需将它扔到视图中,就像您对常规<title>标签所做的那样:
<page-title>{{titleText}}</page-title>
你也可以只包括纯文本,如果你不需要动态:
<page-title>Subpage X</page-title>
或者,你可以使用一个属性,使它更ie友好:
<div page-title>Title: {{titleText}}</div>
当然,你可以在标签中放入任何你想要的文本,包括Angular代码。在本例中,它将查找$scope。无论自定义标题标签当前在哪个控制器中。
只要确保你的页面上没有多个页面标题标签,否则它们会互相攻击。
这里的Plunker例子http://plnkr.co/edit/nK63te7BSbCxLeZ2ADHV。您必须下载压缩文件并在本地运行,才能看到标题的变化。
自定义基于事件的解决方案的灵感来自迈克尔布罗姆利
我不能使它与$scope工作,所以我尝试与rootScope,可能有点脏…(特别是当你在页面上刷新没有注册事件时)
但我真的很喜欢事物松散耦合的想法。
我使用的是angularjs 1.6.9
index.run.js
angular
.module('myApp')
.run(runBlock);
function runBlock($rootScope, ...)
{
$rootScope.$on('title-updated', function(event, newTitle) {
$rootScope.pageTitle = 'MyApp | ' + newTitle;
});
}
anyController.controller.js
angular
.module('myApp')
.controller('MainController', MainController);
function MainController($rootScope, ...)
{
//simple way :
$rootScope.$emit('title-updated', 'my new title');
// with data from rest call
TroncQueteurResource.get({id:tronc_queteur_id}).$promise.then(function(tronc_queteur){
vm.current.tronc_queteur = tronc_queteur;
$rootScope.$emit('title-updated', moment().format('YYYY-MM-DD') + ' - Tronc '+vm.current.tronc_queteur.id+' - ' +
vm.current.tronc_queteur.point_quete.name + ' - '+
vm.current.tronc_queteur.queteur.first_name +' '+vm.current.tronc_queteur.queteur.last_name
);
});
....}
index . html
<!doctype html>
<html ng-app="myApp">
<head>
<meta charset="utf-8">
<title ng-bind="pageTitle">My App</title>
这对我很有用:)