可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I need to insert open graph meta tags on a particular page in an angular app.
These tags are different based on the news or video that the page has.
I tried adding a variable to the $rootscope. This variable will be populated with the meta tags when it is relevant.
Now here is my issue. As soon as this variable gets populated with the HTML string, they don't form a part of the head and are instead outputted to the body. I have searched for a day and could not find any viable solutions. Any help would be appreciated
回答1:
I created an Angular module that can be used to set meta tags dynamically using the $routeProvider
route definitions.
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!'
}
})
});
You can then set the meta tags in HTML like so
<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}}" />
To set the title, description and og:image dynamically, you can inject ngMeta
into your controller
.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');
});
Support for more tags and ui-router are in the works.
回答2:
I was having a similar problem with Apple's Smart App Banner. You may be able to apply a similar logic if you are still looking for an answer.
<html ng-app="myNewsApp">`
<head>
<title> myNews </title>
<meta property="og:url" content={{opengraph.urlArgument()}}/>
</head>
I set up a service that populates the urlArgument with the id as per this answer., and used it in the page controller.
module.controller('myNewsVideoCtrl', function($scope, $stateParams, $rootScope, openGraph ){
$rootScope.opengraph = openGraph;
$rootScope.opengraph.set("http://www.imdb.com/title/"+$stateParams.videoID);
})
回答3:
I want to re-answer this question. Infact, all your need a directive. You should set all your meta values as an object such as : {name:'keywords',content:'angularjs, directive,meta'}
If you want to add it on $rootScope it can be like this :
$rootScope.metas = [{
name:'description',
content :'AngularJS meta example'
},{
name:'keywords',
content :'AngularJS, metas, example'
},{
charset:'UTF-8'
}];
Then you can use object's keys as an attribute and theirs value. Repeat the directive and pass all your metas in it. If you dont want a clear html you can create an empty meta element in javascript and add attributes on it. Then replace the directive element's outerHTML with your the new meta element's outerHTML. You can check this page : Simple Dynamic Meta Tags in AngularJS
回答4:
If you are using ui-router, you can use $stateChangeSuccess
to set dynamically meta description and other meta tags based on current state. You have to put custom meta description in each state defined in $stateProvider.state(...)
.
You must have <meta name="description" content="Default Description">
in HTML markup, then and then document.getElementsByTagName('meta')
will be able to return the meta description tag.
$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;
}
}
});