Интеграция disqus с emberjs работает только при загрузке первой страницы

Я использую ember-1.0.0-rc.5 и создал представление для комментариев disqus, которым я передаю идентификатор статьи.

Моя проблема в том, что disqus не знает, когда я переключаюсь с одной страницы на другую.

Это код вида:

App.DisqusView = Ember.View.extend({
  tagName: 'div',
  elementId: 'disqus_thread',
  didInsertElement: function(){
    var root_url = "http://my-root-url.herokuapp.com"
    var page_id = this.get('identifier');

    /* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
    var disqus_identifier = "item-" + page_id;
    console.log(disqus_identifier);
     / this outputs the correct id/

    var disqus_title = "the song title" ;
    console.log(disqus_title);
     / this outputs the correct title/

    var disqus_url =  root_url + '/#/song/' + page_id;
    console.log(disqus_url);
     / this outputs the correct url for the page/

    var disqus_shortname = 'example'; 

    /* * * DON'T EDIT BELOW THIS LINE * * */
    (function() {
      var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
      dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
      (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    })();
  }
});

и это в моем шаблоне руля:

{{view App.DisqusView identifierBinding="id"}}

Таким образом, комментарии отображаются на всех страницах, но один комментарий сохраняется на всех страницах, как будто disqus думает, что это одна и та же страница.

Я регистрирую page_id и URL, чтобы убедиться, что я даю disqus правильный URL.

также когда я нажимаю на одну страницу на другой, когда обе имеют disqus, консоль выдает кучу ошибок disqus:

DISQUS assertion failed: Unsafe attempt to redefine existing module: stringify [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: parse [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: domready [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: on [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: once [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: off [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: trigger [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: stopListening [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: listenTo [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: listenToOnce [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: bind [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: unbind [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: getShortnameFromUrl [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: getForum [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: isSSL [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: guessThreadTitle [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: getContrastYIQ [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: colorToHex [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: getElementStyle [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: getAnchorColor [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: normalizeFontValue [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: isSerif [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: getBrowserSupport [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: getPermalink [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: expose [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: BaseApp [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: WindowedApp [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: ThreadBoundApp [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: PublicInterfaceMixin [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: Switches [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: Profile [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: BackplaneIntegration [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: Lounge [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: Ignition [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: HostConfig 

4 ответа

Решение

Интеграция Disqus с Ember


Обновление - теперь есть Ember Addon.


Я только что закончил интеграцию Async Disqus в среду блогов ember ( см. Источник здесь), и вот как я это сделал:

Сначала установите параметры как объект (легко доступный для всех компонентов):

App.DisqusOptions = Em.Object.create({
  shortname: 'example', // Set this to your Disqus account's shortname
});

Затем загрузите disqus один раз и только один раз, используя код, который они вам дают. Я сделал это в компоненте:

App.DisqusCommentsComponent = Em.Component.extend({
  setupDisqus: function() {
    if (!window.DISQUS) {
      var disqusShortname = App.DisqusOptions.get('shortname');
      window.disqus_shortname = disqusShortname; // Mimic behaviour as if we're setting variable in a script tag

      var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
      dsq.src = '//' + disqusShortname + '.disqus.com/embed.js';
      (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    }
  }.on('didInsertElement'),
});

Вы также можете сделать это, установив disqusLoaded свойство объекта параметров в значение true после запуска setupDisqus() метод и проверка против этого.

Кроме того, вы можете сделать это в шаблоне приложения, используя script теги, но это приведет к ошибке, если вы загружаете скрипт на страницу, которая не имеет и элемент с id из #disqus_thread,

Далее используйте Em.View или же Em.Component что вы будете размещать на каждой странице, где вы хотите, чтобы комментарии появлялись. Давайте назовем это App.DisqusCommentsComponent, Этот компонент не будет иметь макета (шаблона). Поскольку этот компонент будет загружаться каждый раз, когда мы меняем маршруты / сообщения, это идеальное место для вызова DISQUS.reset(),

App.DisqusCommentsComponent = Em.Component.extend({
  elementId: 'disqus_thread', // ID is used by Disqus to know where to load the comments
  timer: null,

  setupDisqus: function() {
    // setupDisqus() code left out for purposes of not repeating myself
  }.on('didInsertElement'),

  loadNewPostComments: function() {
    if (window.DISQUS) {
      this.reset();
    } else {
      // If DISQUS hasn't finished async loading yet, check again in 100 ms. Once it's loaded, the above this.reset() will be called.
      this.set('timer', Em.run.debounce(this, this.loadNewPostComments, 100));
    }
  },

  reset: function() {
    var controller = this.get('parentView.controller');
    var postIdentifier = controller.get('urlString');
    var postUrl = window.location.href;

    // Since this view has the elementId Disqus targets, we need to wait until after the view has finished rendering to call the reset function, which searches for #disqus_thread
    Em.run.scheduleOnce('afterRender', function() {
      window.DISQUS.reset({
        reload: true,
        config: function () {
          this.page.identifier = postIdentifier;
          this.page.url = postUrl;
        }
      });
    });
  },
});

NB переменная postIdentifier это свойство, установленное на контроллере для каждого сообщения в блоге, загруженное как модель контроллера. Вам понадобится аналогичный способ определения каждого маршрута для отслеживания комментариев.

И вуаля! Ваш асинхронный вызов будет выполняться каждый раз, когда пользователь меняет маршруты на маршрут, на котором есть компонент комментариев в своем шаблоне. Например:

// Some random hbs here for your blog post
{{disqus-comments}}

Disqus JS Конфигурационные переменные

Всякий раз, когда вы устанавливаете переменную конфигурации, подобную этой, вы захотите установить их как свойство в окне. Например:

var disqusShortname = App.DisqusOptions.get('shortname');
window.disqus_shortname = disqusShortname;

// Do stuff with disqusShortname here

Sidenote: Количество комментариев

Если вы хотите использовать функцию подсчета комментариев в Disqus, вы можете использовать подход, аналогичный описанному выше. Тем не менее, вам также нужно будет снова открыть представление {{link-to}} вспомогательные вызовы с чем-то вроде следующего:

Em.LinkView.reopen({

  addDisqusTag: function() {
    var commentCount = this.get('commentCount');

    if (commentCount) {
      var isLinkToPost = this.get('isLinkToPost');
      var href = this.get('href');
      var disqusTag = '#disqus_thread';

      this.set('href', href + disqusTag);
    }
  }.on('willInsertElement'),
});

Теперь, если вы сделаете следующее в своем шаблоне, он вернет комментарий Count:

{{#link-to 'post' this.urlString commentCount='true'}}{{/link-to}}

Надеюсь, это поможет. Дайте знать, если у вас появятся вопросы!

В соответствии с документацией Disqus вы можете сбросить активный поток следующим образом:

DISQUS.reset({
  reload: true,
  config: function () {  
    this.page.identifier = "newidentifier";  
    this.page.url = "http://example.com/#!newthread";
  }
});

http://help.disqus.com/customer/portal/articles/472107-using-disqus-on-ajax-sites)

Использование:

  • Компонент
  • didInsertElement()

Компонент

App.CDisqusComponent = Em.Component.extend({
    didInsertElement: function () {
        var page_id = window.location.href,
            disqus_identifier = page_id,
            disqus_url = page_id,
            disqus_title = Em.$('title').text(),
            disqus_shortname = 'disqus shortname', // CHANGE, USE YOURS
            el_id = disqus_shortname + Date.now();

        this.set('page_id', el_id);

        var dsq = document.createElement('script');
        dsq.type = 'text/javascript';
        dsq.async = true;
        dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
        dsq.id = el_id;
        (document.getElementsByTagName('head')[0] || 
         document.getElementsByTagName('body')[0]).appendChild(dsq);
    },
    willDestroyElement: function () {
        Em.$('#' +  this.get('page_id')).remove();
    }
})

Шаблон компонента

<div id="disqus_thread"></div>

Теперь вы можете добавить disqus в любой шаблон с помощью:

{{c-disqus}}

раскошелиться: https://gist.github.com/givanse/a3b945a47438d7119989

Я создал рабочий jsbin, посмотрите.

Что касается того, что я изменил, эта строка была немного неправильной

this.get('element').id = 'disqus_thread';

но также может быть опущен путем определения elementId на самом представлении с помощью

App.DisqusView = Ember.View.extend({
  tagName: 'div',
  elementId: 'disqus_thread',
  ...

И затем извлекается с

  var page_id = this.get('elementId');

Чтобы проверить, что он работает, я поместил в jsbin вверху ссылку на псевдо-страницу о странице, на странице о странице вы найдете ссылку обратно на страницу индекса, переключаясь назад и вперед, я не вижу никаких проблем, Disqus загружается каждый раз, как и ожидалось, хотя ошибки все еще появляются. Это может быть связано с тем, как Disqus вводится в DOM. Пожалуйста, посмотрите и дайте мне знать, если это работает для вас.

Надеюсь, поможет.

Другие вопросы по тегам