How can I update meta tags in AngularJS?

廉价感情. 提交于 2019-11-26 20:20:36
Vijayabaskaran M
<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>

If you use angular-ui-router, you can use ui-router-metatags.

I solved this very issue about 2 days ago, by creating a service, and using $window, plus some classic javascript.

In your html mark-up create whatever metatags you need... (feel free to leave them blank for now, or you can set them to a default value.)

<head> 
    <meta name="title"/>
    <meta name="description"/>
</head>

Then we'll need to create a service like so.

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;
 }; 
}]);

Now we'll need to use the "self.setMetaTags" service from within the controller (upon initialization)... you'll simply call the function anywhere on the controller.

  angular.module('app').controller('TestController', ['MetadataService',function(MetadataService){

   MetadataService.setMetaTags({
       title: 'this',
       description: 'works'
    });

   }]);

When you do 'view source' in most browsers, you see the document that was originally sent from the server before any JavaScript manipulation of the DOM. AngularJS apps typically do a lot of DOM manipulation but it never actually changes the original document. When you do something like right click -> inspect element in FireFox or Chrome (with dev tools) you will see the rendered DOM that includes all the JavaScript updates.

So, to answer your question there is no way to update the description meta tag with JavaScript such that the changes will be reflected in 'view source'. However, you can update the meta description tag so that any browser plugins (ex. bookmark apps, etc.) will see the updated description. To do that you would do something like this:

var metaDesc = angular.element($rootElement.find('meta[name=description]')[0]); metaDesc.attr('content', description);

Engineer_Andrew

I tweaked the answer found here to make this work on my site. You establish the meta content in the route config and then bind a function to the $routeChangeSuccess event to put the configured value into the $rootScope. As long as your meta tag is bound to the $rootScope value, everything will work out as planned.

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>
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!