你们中的任何人都已经想出了如何在SPA模式下使用AngularJS处理元标记的优雅方法吗?
在基本模板中,我有一些默认的元标记。对于每个路由,每个控制器正在加载具有不同内容的不同视图。很正常。但是,如何更改每个页面的元标记?
此外,某些页面应包含更多元标记,而其他页面则更少。例如,包含内容的页面应具有用于社交媒体共享的附加元标记。其他敏感页面应该有no-follow元标记,禁止机器人索引页面。
很奇怪经验丰富的人如何处理这个问题?
答案 0 :(得分:23)
我使用的模式来自ngBoilerplate项目。在这种模式中,有一个整体的应用程序控制器,处理一个"全球"范围,包括元标记。
您的个人页面'如果您使用默认路由器,控制器可以在导航到$locationChangeSuccess
时发出事件。
app控制器侦听此事件,并在ngBoilerplate的情况下使用它来更新页面标题:https://github.com/ngbp/ngbp/blob/v0.3.2-release/src/app/app.js#L17-L21
然而,没有什么可以阻止你用你喜欢的任何元标记信息发出一个对象,然后让你有一个监听器。
// on your individual app pages goes something like this
function SomePageController($scope) {
// the event gets fired when the page is loaded and the controller is called.
$scope.$emit('newPageLoaded', { 'title': 'Some Page', 'description': 'blah' });
}
// your overall app controller
function AppController($scope) {
$scope.metadata = {
'title': 'default title',
'description': 'default description',
};
// whenever a controller emits the newPageLoaded event, we update the app's metadata
$scope.$on('newPageLoaded', function(event, metadata) {
$scope.metadata = metadata
});
}
然后在你的标题中你可以这样做:
<html ng-app="myApp" ng-controller="AppController">
<head>
<meta title="{{ metadata.title }}" ng-if="metadata.title" />
<meta description="{{ metadata.description}}" ng-if="metadata.description" />
<meta whatever="{{ metadata.whatever}}" ng-if="metadata.whatever" />
</head>
我没有测试过此代码,因此可能存在错误,但我认为一般原则是合理的。
在您的问题中,您提到了为社交媒体共享整合标记的用例。我认为你的意思是开放式图形或推特等。
在这种情况下,重要的是要知道目前这些网站(facebook,twitter,pinterest等)使用的抓取工具将不执行您的JavaScript,因此无法读取任何元标记您使用Angularjs动态填充。
我已经撰写了一篇关于此问题的博客文章,其中包含一个建议的解决方案:http://www.michaelbromley.co.uk/blog/171/enable-rich-social-sharing-in-your-angularjs-app/