Angular动态头部meta标签

4

我需要在一个angular应用程序的特定页面上插入开放图元标签。

这些标签根据页面拥有的新闻或视频不同而不同。

我尝试向$rootscope添加变量。当相关时,此变量将填充元标记。

现在我的问题是,一旦此变量被HTML字符串填充,它们就不会成为head的一部分,而是输出到body中。我已经搜索了一天,但没有找到可行的解决方案。任何帮助都将不胜感激。


你把ng-app放在头部级别还是主体级别了吗? - Valéry
你能贴一些代码吗? - Avraam Mavridis
4个回答

11

我创建了一个Angular模块,可以使用$routeProvider路由定义动态设置元标签。

angular.module('YourApp','ngMeta')
.config(function ($routeProvider, ngMetaProvider) {

  $routeProvider
  .when('/home', {
    templateUrl: 'home-template.html',
    meta: {
      //Sets 'Home Page' as the title when /home is open
      title: 'Home page', 
      description: 'This is the description of the home page!'
    }
  })
  .when('/login', {
    templateUrl: 'login-template.html',
    meta: {
      //Sets 'Login Page' as the title when /login is open
      title: 'Login page',
      description: 'Login to this wonderful website!'
    }
  })
});

然后您可以像这样在HTML中设置元标签

<title ng-bind="ngMeta.title"></title>
<!-- OR <title>{{ngMeta.title}}</title> -->    

<!-- This meta tag can be set using ngMetaProvider -->
<meta property="og:type" content="{{ngMeta.ogType}}" />

<!-- Default locale is en_US -->
<meta property="og:locale" content="{{ngMeta.ogLocale}}" />

<!-- This meta tag changes based on the meta object of each route -->
<!-- or when the setDescription function is called -->
<meta name="description" content="{{ngMeta.description}}" />

为了动态设置标题、描述和og:image,您可以将ngMeta注入到您的控制器中。

.controller('DemoCtrl', function(ngMeta) {

    ngMeta.setTitle('Demo page');
    ngMeta.setDescription('This is the description of the demo page');
    ngMeta.setOgImgUrl('http://example.com/abc.jpg');
});

我们正在开发更多标签和 ui-router 的支持。


2
我认为setDescription(String value)在当前版本中不可用,但是setTag(String tagName, String value)可以完成这项工作。 - Watchmaker

1

我曾经遇到过苹果的智能应用横幅类似的问题。如果你还在寻找答案,或许可以采用类似的逻辑来解决。

<html ng-app="myNewsApp">`
<head>
  <title> myNews </title>
  <meta property="og:url" content={{opengraph.urlArgument()}}/>
</head>

我设置了一个服务,根据this answer.中的id填充urlArgument,并在页面控制器中使用它。
module.controller('myNewsVideoCtrl', function($scope, $stateParams, $rootScope, openGraph ){
  $rootScope.opengraph = openGraph;
  $rootScope.opengraph.set("http://www.imdb.com/title/"+$stateParams.videoID);
})

1
我希望重新回答这个问题。实际上,你需要一个指令。你应该将所有的元数据值设置为一个对象,例如:{name:'keywords',content:'angularjs, directive,meta'} 如果你想将它添加到$rootScope中,可以像这样:
$rootScope.metas = [{
  name:'description',
  content :'AngularJS meta example'
},{
  name:'keywords',
  content :'AngularJS, metas, example'
},{
  charset:'UTF-8'
}];

然后,您可以使用对象的键作为属性和它们的值。重复指令并将所有元数据传递给它。如果您不想要清晰的HTML,则可以在JavaScript中创建一个空的meta元素,并在其中添加属性。然后,将指令元素的outerHTML替换为新meta元素的outerHTML。您可以查看此页面:AngularJS中的简单动态元标记


0
如果您正在使用ui-router,您可以使用$stateChangeSuccess根据当前状态动态设置元描述和其他元标记。您必须在$stateProvider.state(...)中定义的每个状态中放置自定义元描述。
您必须在HTML标记中有<meta name="description" content="Default Description">,然后document.getElementsByTagName('meta')才能返回元描述标记。
$stateProvider
    .state('app.about', {
        url: 'about',
        templateUrl: '/modules/core/client/views/about.client.view.html',
        controller: 'AboutController',
        controllerAs: 'vm',
        metaDesc: 'Learn about my awesome social site.',
        data: {
            pageTitle: 'About | The Social Site'
        }
    })

$rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams) {

    var metaDesc = $state.current.metaDesc || "Default Meta Description";

    var metas = document.getElementsByTagName('meta');

    for (let i = 0; i < metas.length; i++) {
        if (metas[i].getAttribute("name") === "description") {
            metas[i].setAttribute("content", metaDesc);
            break;
        }
    }
});

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