AngularJS和单页应用程序模式下的元标记

12

有没有人已经找到了一种优雅的方法来处理AngularJS在SPA模式下的元标记?

在基本模板中,我有一些默认的元标记。对于每个路由,每个控制器都会加载不同的内容视图。非常正常。但是如何为这些页面的每个页面更改元标记呢?

此外,某些页面应具有更多的元标记,其他页面则应具有较少的元标记。例如,具有内容的页面应具有用于社交媒体共享的附加元标记。其他敏感页面应具有no-follow元标记以禁止机器人索引该页面。

好奇那些有经验的人是如何应对这个问题的?

1个回答

23

我使用的一种模式来自于ngBoilerplate项目。在这种模式中,有一个整体应用控制器,处理“全局”范围内的内容,包括元标签。

如果您正在使用默认路由器,则您各个页面的控制器可以在导航到它们时发射一个事件,$locationChangeSuccess

应用程序控制器监听此事件,并在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>

我没有测试这段代码,所以可能会有错误,但我认为总体原则是正确的。

关于社交媒体分享的注意事项

在你的问题中,你提到了在社交媒体分享中整合标签的用例。我想你指的是像开放图谱或Twitter等。

在这种情况下,重要的是要知道目前这些网站(Facebook、Twitter、Pinterest等)使用的爬虫程序将不会执行你的JavaScript代码,因此无法读取你使用AngularJS动态填充的任何元标记。

我写了一篇关于这个问题的博客文章,并提出了一个解决方案:http://www.michaelbromley.co.uk/blog/171/enable-rich-social-sharing-in-your-angularjs-app/


@MichaelBromley,我读了你的文章,非常棒。你知道用nginx怎么做吗?我正在运行NodeJS、ExpressJS和AngularJS。 - andrewoodleyjr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接