2013-04-20 23 views
32

Sto sviluppando un'applicazione utilizzando AngularJS. Voglio aggiornare i meta tag sul cambio di rotta.
Come posso aggiornare i meta tag in AngularJS che possono essere visualizzati in "Visualizza sorgente" nella pagina?Come posso aggiornare i meta tag in AngularJS?

ecco un codice 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

Si sta utilizzando 'ng-view', in quanto l'applicazione Web è un'applicazione di una sola pagina che modifica solo le viste? – callmekatootie

+0

non è possibile aggiornare 'view source' ... che è ciò che il server invia. Spiega più in dettaglio cosa stai cercando di fare – charlietfl

+0

sì sto usando ng-view .. – Amb

risposta

1

Quando si esegue 'vista origine' nella maggior parte dei browser, si vede il documento che è stato originariamente inviato dal server prima di qualsiasi manipolazione del DOM JavaScript. Le app AngularJS in genere eseguono molte manipolazioni DOM ma non cambiano mai effettivamente il documento originale. Quando fai qualcosa come il tasto destro del mouse -> controlla elemento in FireFox o Chrome (con gli strumenti di sviluppo) vedrai il DOM renderizzato che include tutti gli aggiornamenti JavaScript.

Quindi, per rispondere alla tua domanda non c'è modo di aggiornare il meta tag della descrizione con JavaScript in modo tale che le modifiche si riflettano in "Visualizza sorgente". Tuttavia, puoi aggiornare il tag meta description in modo che tutti i plug-in del browser (ad esempio le app dei segnalibri e così via) vedano la descrizione aggiornata. Per fare questo si potrebbe fare qualcosa di simile:

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

+0

Stiamo esaminando anche questo problema, e una potenziale soluzione che stiamo esaminando è di aggiungere una direttiva alla sezione che aggiorna i tag META corrispondenti basati su una chiamata $ emit() attivata durante l'evento $ routeChangeSuccess ... –

+1

@dacopenhagen È passato un po 'di tempo da quando mi trovavo in quel progetto, ma se ricordo correttamente abbiamo implementato una direttiva personalizzata, e anche finito utilizzando un servizio di terze parti (dimenticare il nome) per servire ogni pagina come contenuto pre-renderizzato ai motori di ricerca per scopi di SEO –

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

Hai ragione. Ma sto usando #! soluzione hashbang di Google in modo che le pagine statiche abbiano i meta tag renderizzati. – nathanengineer

+0

Ho lo stesso problema e la tua soluzione non funziona (errori JS) anche se ho corretto i vari errori di battitura ... Potresti correggere la tua risposta e spiegare un po 'per renderla una vera risposta? Grazie. – c4k

+0

Pls verificare la sezione init di ng-app: sostituire con e sostituire con e funziona ... –

0

ho ottimizzato la risposta trovata here per fare questo lavoro sul mio sito. Stabilisci il meta contenuto nella route config e quindi associa una funzione all'evento $ routeChangeSuccess per inserire il valore configurato in $ rootScope. Finché il tuo meta tag è legato al valore $ rootScope, tutto funzionerà come pianificato.

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

Perché il titolo del contenuto ng-bind, gli altri tra parentesi {{}}? – ShibinRagh

+0

@ShibinRagh Penso che inizialmente stavo usando ng-bind e poi l'ho sostituito con doppie parentesi graffe. Devo essermi perso quello sul titolo. Ho ricontrollato e usare i doppi riccioli sul titolo funziona anche bene. Tuttavia, ho trovato che questa soluzione non funziona con un'impostazione "altrimenti". Forse un giorno penserò a un altro modo. –

6

Ho risolto questo problema circa 2 giorni fa, con la creazione di un servizio, e l'utilizzo di $ finestra, oltre ad alcuni javascript classico.

nel codice HTML mark-up creare qualsiasi metatag è necessario ... (sentitevi liberi di lasciare loro in bianco per ora, oppure è possibile impostare un valore predefinito.)

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

poi ne bisogno di creare un servizio come questo

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

Ora abbiamo bisogno di utilizzare il servizio "self.setMetaTags" dal di dentro il controller (durante l'inizializzazione) ... sarà sufficiente chiamare la funzione in qualsiasi punto del controller.

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

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

    }]); 
+2

+1, ma ha funzionato solo con me quando ho cambiato '$ window.document.getElementsByName ('title') [0] .content = tagData.title;' a '$ window.document.title = tagData.title' –