2016-08-23 2 views
0

Я слежу за этим уроком и попытался использовать сервис для динамических метаданных seo. https://weluse.de/blog/angularjs-seo-finally-a-piece-of-cake.htmlСлужба AngularJS для хранения метаданных SEO

Однако возникает проблема. Похоже, что услуга недоступна вне контроля контроллера. <div ui-view></div>

Вот сервис я пытаюсь выполнить:

app.service('SeoMetaService', function() { 

     var metaDescription = ''; 
     var metaKeywords = ''; 
     var title = ''; 
     return { 
      metaDescription: function() { return metaDescription; }, 
      metaKeywords: function() { return metaKeywords; }, 
      title: function() { return title; }, 

      reset: function() { 
       metaDescription = ''; 
       metaKeywords = ''; 
       title = ''; 
      }, 
      setMetaDescription: function(newMetaDescription) { 
       metaDescription = newMetaDescription; 
      }, 
      appendMetaKeywords: function(newKeywords) { 
       for(var i=0;i<newKeywords.length;i++){ 
         if (metaKeywords === '') { 
          metaKeywords += newKeywords[i]; 
         } else { 
          metaKeywords += ', ' + newKeywords[i]; 
         } 
       } 
      }, 
      setTitle: function(newTitle) { title = newTitle; } 
     }; 
    }); 

использование в контроллере:

app.controller('WelcomeController',['$scope', 'SeoMetaService', function($scope, SeoMetaService) { 
$(document).ready(function() { 
    var keywords = ["bla bla","bla bla blah"]; 
    SeoMetaService.setTitle("title bla bla bla"); 
    SeoMetaService.setMetaDescription("description bla bla bla"); 
    SeoMetaService.appendMetaKeywords(keywords); 

    console.log(SeoMetaService.metaDescription()); 
    console.log(SeoMetaService.metaKeywords()); 
}); 
}]); 

на главной странице (одна-страница-приложение), упрощена:

<html ng-app="MainPage"> 
<head> 
    <title>{{SeoMetaService.title()}}</title> 

    <meta name="description" content="{{ SeoMetaService.metaDescription() }}"> 
    <meta name="keywords" content="{{ SeoMetaService.metaKeywords() }}"> 
    <base href="/"> 
</head> 

<body> 
<div ui-view></div> 
</body> 

Таким образом, проблема равна - i считал, что угловые службы являются одноточечными. Но после запуска контроллера и установки данных он не отображается в HTML.

Как исправить/что делать?

+0

Не используйте jQuery ('$ (document) .ready()') внутри углового контроллера. Вам это не нужно, и вы не должны взаимодействовать с DOM каким-либо образом внутри контроллера. – deceze

+0

Почему бы и нет? я иногда использую. – user1935987

+0

Зачем? Документ * * будет готов к моменту выполнения контроллера, поэтому он лишний. И вы не должны манипулировать DOM от контроллеров, потому что тогда вы вернетесь к созданию jQuery mush.Одной из основных сильных сторон Angular является строгое разделение на сервисы/контроллеры/представления, что делает ваше приложение более модульным и поддерживаемым, если вы это сделаете правильно. После того, как вы начнете писать полные сложные приложения, и вам нужно расти и модифицировать их, вы быстро попадаете в уродливые пятна при привязке контроллера к DOM. – deceze

ответ

1

Я предполагаю, что вы определили WelcomeController на уровне зрения.

So SeoMetaService можно увидеть только во внутреннем html, представленном в <div ui-view></div>.

Вам нужно определить контроллер WelcomeController на уровне <html> или <head>, потому что SeoMetaService доступен только внутри тега, определяющего контроллер WelcomeController.

Кроме того, вам необходимо удалить ссылку на JQuery и выставить SeoMetaService в $scope.

Код должен быть примерно таким.

HTML-:

<head ng-controller='WelcomeController'> 
<title>{{SeoMetaService.title()}}</title> 

    <meta name="description" content="{{ SeoMetaService.metaDescription() }}"> 
    <meta name="keywords" content="{{ SeoMetaService.metaKeywords() }}"> 
    <base href="/"> 
</head> 

Контроллер обновление:

app.controller('WelcomeController',['$scope', 'SeoMetaService', function($scope, SeoMetaService) { 

    var keywords = ["bla bla","bla bla blah"]; 
    SeoMetaService.setTitle("title bla bla bla"); 
    SeoMetaService.setMetaDescription("description bla bla bla"); 
    SeoMetaService.appendMetaKeywords(keywords); 

    console.log(SeoMetaService.metaDescription()); 
    console.log(SeoMetaService.metaKeywords()); 

    // Added to the scope SeoMetaService 
    $scope.SeoMetaService = SeoMetaService; 


}]); 

Обратите внимание, что вы можете изменить содержание SeoMetaService и в другом контроллере, так, например, изменяя вид вы можете обновить заголовок, мета-описание и мета-ключевые слова, отражающие содержание нового представления. Вот возможный пример для контроллера MyViewController

app.controller('MyViewController',['$scope', 'SeoMetaService', function($scope, SeoMetaService) { 

    var keywords = ["xxx","yyy"]; 
    SeoMetaService.setTitle("title my view"); 
    SeoMetaService.setMetaDescription("description my view"); 
    SeoMetaService.appendMetaKeywords(keywords); 

}]); 

При входе в вид с помощью контроллера MyViewController ключевых слов, название, мета описание и мета ключевые слова будут обновлены.

+0

Услуга также не отображается на контроллере или в какой-либо области, поэтому это само по себе не поможет ... – deceze

+0

@deceze вы правы. Я добавил также SeoMetaService в область $ в этом примере –

+0

Итак, как я понял, мне нужно создать контроллер для '', чтобы объявить в нем 'SeoMetaService', а затем я смогу изменить его с контроллеров которые находятся в теге '', правильно? – user1935987

Смежные вопросы