如何更新 AngularJS 中的元标记?
Posted
技术标签:
【中文标题】如何更新 AngularJS 中的元标记?【英文标题】:How can I update meta tags in AngularJS? 【发布时间】:2013-04-13 17:15:38 【问题描述】:我正在使用 AngularJS 开发一个应用程序。我想在路线更改时更新元标记。 如何更新 AngularJS 中可以显示在页面“查看源代码”中的元标记?
这是一个 html 代码 -
<!DOCTYPE html>
<html ng-app="app">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="fragment" content="!" />
<meta name="title" content="Test App">
<meta name="description" content="Test App">
<meta name="keywords" content="Test,App">
<link rel="stylesheet" href="css/jquery-ui-1.10.2.custom.min.css" />
<link rel="stylesheet" href="css/extra.css" />
<script src="js/libs/jquery-1.8.3.min.js"></script>
<script src="js/libs/jquery-ui-1.10.2.custom.min.js"></script>
<script src="js/libs/angular.min.js"></script>
<script src="js/controller.js"></script>
<script src="js/routes.js"></script>
</head>
<body>
<div ng-controller="mainCtrl" class="main-container" loading>
<div class="container-holder">
<div class="container">
<div ng-include src='"elements/header.html"'></div>
<div ng-view class="clearfix"></div>
</div>
</div>
<div ng-controller="userCtrl" id="test">
<div class="container" class="login-container">
<div id="login-logo">
<img src="images/logo-300.png" class="login-img"/>
<br />
<div ng-view></div>
</div>
</div>
</div>
</body>
</html>
【问题讨论】:
您使用的是ng-view
,因为您的Web 应用程序是一个仅更改视图的单页应用程序吗?
您无法更新view source
...这是服务器发送的内容。更详细地解释你想要做什么
是的,我正在使用 ng-view..
如果这与 SEO 相关...您需要一个服务器端解决方案。使用 javascript 在浏览器中更改它们没有任何好处
@charlietfl 现代网络爬虫(google、bing)支持 JS 的无头执行,它们会爬取用客户端 JS 编写的网络应用。
【参考方案1】:
<html ng-app="app">
<title ng-bind="metaservice.metaTitle()">Test</title>
<meta name="description" content=" metaservice.metaDescription() " />
<meta name="keywords" content=" metaservice.metaKeywords() " />
<script>
var app = angular.module('app',[]);
app.service('MetaService', function()
var title = 'Web App';
var metaDescription = '';
var metaKeywords = '';
return
set: function(newTitle, newMetaDescription, newKeywords)
metaKeywords = newKeywords;
metaDescription = newMetaDescription;
title = newTitle;
,
metaTitle: function() return title; ,
metaDescription: function() return metaDescription; ,
metaKeywords: function() return metaKeywords;
);
app.controller('myCtrl',function($scope,$rootScope,MetaService)
$rootScope.metaservice = MetaService;
$rootScope.metaservice.set("Web App","desc","blah blah");
);
</script>
<body ng-controller="myCtrl"></body>
</html>
【讨论】:
你是对的。但我正在使用 #! Google 的 hashbang 解决方案,因此静态页面具有呈现的元标记。 我有同样的问题,即使我纠正了几个错别字,您的解决方案也不起作用(JS 错误)...您能否更正您的答案并稍微解释一下以使其成为真正的答案?谢谢。 请验证 ng-app init 部分: 替换为 和 替换为 并且它正在工作... 这也很有用cssfacts.com/simple-dynamic-meta-tags-in-angularjs 这是否会显示在查看源代码中...这是否可以在 google“fetch as google”中追踪【参考方案2】:大约 2 天前,我通过创建服务并使用 $window 以及一些经典的 javascript 解决了这个问题。
在您的 html 标记中创建您需要的任何元标记...(暂时将它们留空,或者您可以将它们设置为默认值。)
<head>
<meta name="title"/>
<meta name="description"/>
</head>
然后我们需要像这样创建一个服务。
angular.module('app').service('MetadataService', ['$window', function($window)
var self = this;
self.setMetaTags = function (tagData)
$window.document.getElementsByName('title')[0].content = tagData.title;
$window.document.getElementsByName('description')[0].content = tagData.description;
;
]);
现在我们需要在控制器中使用“self.setMetaTags”服务(在初始化时)...您只需在控制器的任何位置调用该函数。
angular.module('app').controller('TestController', ['MetadataService',function(MetadataService)
MetadataService.setMetaTags(
title: 'this',
description: 'works'
);
]);
【讨论】:
+1,但仅当我将$window.document.getElementsByName('title')[0].content = tagData.title;
更改为 $window.document.title=tagData.title
时它才对我有效【参考方案3】:
如果你使用angular-ui-router,你可以使用ui-router-metatags。
【讨论】:
【参考方案4】:当您在大多数浏览器中执行“查看源代码”时,您会看到在对 DOM 进行任何 JavaScript 操作之前最初从服务器发送的文档。 AngularJS 应用程序通常会进行大量的 DOM 操作,但它从未真正更改原始文档。当您在 FireFox 或 Chrome(使用开发工具)中右键单击 -> 检查元素时,您将看到包含所有 JavaScript 更新的渲染 DOM。
因此,要回答您的问题,无法使用 JavaScript 更新描述元标记,以便更改将反映在“查看源代码”中。但是,您可以更新元描述标签,以便任何浏览器插件(例如书签应用程序等)都可以看到更新后的描述。为此,您将执行以下操作:
var metaDesc = angular.element($rootElement.find('meta[name=description]')[0]);
metaDesc.attr('content', description);
【讨论】:
我们也在调查这个问题,我们正在审查的一个潜在解决方案是在 部分添加一个指令,该指令根据触发的 $emit() 调用更新相应的 META 标签在 $routeChangeSuccess 事件期间... @dacopenhagen 自从我参与那个项目以来已经有一段时间了,但如果我没记错的话,我们实现了一个自定义指令,并且最终还使用了第 3 方服务(忘记了名字)来为每个页面作为搜索引擎的预渲染内容用于 SEO 目的 自编写此答案以来,Google 现在在抓取页面时会运行 javascript,因此对 Angular 所做的元标记的更改(未出现在“查看源代码”中)将被 Google 获取。 【参考方案5】:我调整了找到的答案 How to dynamically change header based on AngularJS partial view? 以使其在我的网站上工作。您在路由配置中建立元内容,然后将函数绑定到$routeChangeSuccess
事件以将配置的值放入$rootScope
。只要您的元标记绑定到 $rootScope
值,一切都会按计划进行。
angularApp.run(['$rootScope', function ($rootScope)
$rootScope.$on('$routeChangeSuccess', function (event, current, previous)
$rootScope.title = current.$$route.title;
$rootScope.description = current.$$route.description;
$rootScope.keywords = current.$$route.keywords;
);
]);
angularApp.config(function ($routeProvider, $locationProvider)
$routeProvider
.when('/About',
templateUrl: 'Features/About/About.html',
title: 'Here\'s the Title',
description: 'A Nice Description',
keywords: 'Some, Keywords, Go, Here'
);
// use the HTML5 History API
$locationProvider.html5Mode(true);
$locationProvider.hashPrefix('!');
);
<head>
<meta charset="utf-8" />
<meta name="keywords" content="keywords"/>
<meta name="description" content="description">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="fragment" content="!" />
<title ng-bind="title">A Placeholder Title</title>
<link rel="icon" href="/Images/Logo.ico">
<base href="/" />
@Styles.Render("~/Content/css")
</head>
【讨论】:
为什么标题内容 ng-bind ,其他在括号 ? @ShibinRagh 我想我最初使用的是 ng-bind,然后将其换成了双花括号。我一定只是错过了标题上的那个。我仔细检查并在标题上使用双卷曲也很好。但是,我确实发现此解决方案不适用于“否则”设置。也许有一天我会想办法解决这个问题。以上是关于如何更新 AngularJS 中的元标记?的主要内容,如果未能解决你的问题,请参考以下文章
在 AngularJS 应用程序中单击 Google 地图中的标记不会更新显示的数据