Интеграция 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. Пожалуйста, посмотрите и дайте мне знать, если это работает для вас.
Надеюсь, поможет.