2013-04-20 56 views
32

我正在開發一個使用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> 
+0

您是否在使用'ng-view',因爲在您的web應用程序中只有一個頁面應用程序只改變視圖? – callmekatootie 2013-04-20 12:09:48

+0

你無法更新'view source' ...這是服務器發送的內容。更詳細地解釋你想做什麼 – charlietfl 2013-04-20 12:14:42

+0

是的,我正在使用ng-view .. – Amb 2013-04-20 12:15:41

回答

1

當您在大多數瀏覽器「查看源文件」,你看,最初是從服務器的DOM的任何JavaScript操作之前發送的文檔。 AngularJS應用程序通常會執行大量DOM操作,但它實際上從未改變原始文檔。當你做點右鍵點擊 - >檢查FireFox或Chrome中的元素(使用開發工具)時,你會看到包含所有JavaScript更新的呈現DOM。

因此,要回答您的問題,無法使用JavaScript更新描述元標記,以便更改將反映在「查看源代碼」中。但是,您可以更新元描述標籤,以便任何瀏覽器插件(例如書籤應用程序等)都能看到更新的描述。要做到這一點,你會做這樣的事情:

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

+0

我們也在研究這個問題,我們正在審查的一個潛在解決方案是向更新的部分添加指令在$ routeChangeSuccess事件期間觸發$ emit()調用的相應META標記... – 2014-07-31 17:43:45

+1

@dacopenhagen自從我開始使用該項目以來,已經有一段時間了,但是如果我記得我們正確地實現了自定義指令,使用第三方服務(忘記名稱)將每個頁面作爲預先呈現的內容提供給搜索引擎用於SEO目的 – 2015-08-30 00:07:55

31
<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> 
+0

您是對的。但我正在使用#! hashbang解決方案,所以靜態頁面具有渲染元標記。 – nathanengineer 2014-11-15 17:03:24

+0

即使我糾正了幾個錯別字,我也遇到了同樣的問題,並且您的解決方案無法正常工作(JS錯誤)...您能否糾正您的答案並解釋一點讓它成爲真正的答案?謝謝。 – c4k 2015-03-19 15:59:59

+0

請驗證ng-app初始化部分: 用和替換爲並且它正在工作... – 2016-03-26 15:37:49

0

我調整了答案發現here,使我的網站上這項工作。您在路由配置中建立元內容,然後將函數綁定到$ 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> 
+0

爲什麼標題內容ng-bind,括號{}}中的其他人? – ShibinRagh 2016-10-07 08:16:42

+0

@ShibinRagh我想我最初使用的是ng-bind,然後將它切換爲雙曲花括號。我一定錯過了冠軍頭銜。我仔細檢查,並使用標題作品的雙曲線也很好。但是,我確實發現這種解決方案不適用於「其他」設置。也許有一天我會找出另一種方式。 – 2016-10-12 21:14:16

6

我解決了這個問題非常大約2天前,通過創建服務,並使用$窗口,再加上一些經典的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' 
    }); 

    }]); 
+2

+1,但它只適用於當我更改'$ window.document.getElementsByName('title')[0] .content = tagData.title;'到'$ window.document.title = tagData.title' – 2016-03-01 09:23:25