Как я могу обновить метатеги в AngularJS?
Я разрабатываю приложение, используя 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" alt="" class="login-img"/>
<br />
<div ng-view></div>
</div>
</div>
</div>
</body>
</html>
5 ответов
<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>
Я решил эту проблему около 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'
});
}]);
Если вы используете https://github.com/angular-ui/ui-router, вы можете использовать ui-router-metatags.
Я подправил ответ, найденный здесь, чтобы сделать эту работу на моем сайте. Вы устанавливаете мета-содержимое в конфигурации маршрута, а затем привязываете функцию к событию $ 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>
Когда вы делаете "просмотр исходного кода" в большинстве браузеров, вы видите документ, который был первоначально отправлен с сервера перед любыми манипуляциями JavaScript с DOM. Приложения AngularJS обычно выполняют много манипуляций с DOM, но фактически никогда не изменяют исходный документ. Когда вы сделаете что-то вроде щелчка правой кнопкой мыши -> проверить элемент в FireFox или Chrome (с помощью инструментов dev), вы увидите обработанный DOM, который включает все обновления JavaScript.
Поэтому, чтобы ответить на ваш вопрос, нет способа обновить метатег описания с помощью JavaScript, чтобы изменения были отражены в "представлении источника". Однако вы можете обновить мета-тег описания, чтобы любые плагины браузера (например, приложения закладок и т. Д.) Увидели обновленное описание. Для этого вы должны сделать что-то вроде этого:
var metaDesc = angular.element($rootElement.find('meta[name=description]')[0]);
metaDesc.attr('content', description);