在单页应用程序中使用 Disqus 的最佳方法是什么?
我看到 angular js docs 已经成功实现了它。
目前我们的方法在我们的 AngularJS 应用程序中看起来像这样,但它似乎不稳定,难以测试,并且加载了错误的线程 ID(几乎所有地方都加载了相同的线程)。
'use strict';
angular.module('studentportalenApp.components')
.directive('disqusComponent',['$log', '$rootScope', function($log, $rootScope) {
var _initDisqus = function _initDisqus(attrs)
{
if(window.DISQUS) {
DISQUS.reset({
reload: true,
config: function () {
this.page.identifier = attrs.threadId;
this.disqus_container_id = 'disqus_thread';
this.page.url = attrs.permalinkUrl;
}
});
}
else
{
$log.error('window.DISQUS did not exist before directive was loaded.');
}
}
//Destroy DISQUS bindings just before route change, to properly dispose of listeners and frame (postMessage nullpointer exception)
$rootScope.$on('$routeChangeStart', function() {
if(window.DISQUS) {
DISQUS.reset();
}
});
var _linkFn = function link(scope, element, attrs) {
_initDisqus(attrs);
}
return {
replace: true,
template: '<div id="disqus_thread"></div>',
link: _linkFn
};
}]);
最佳答案
我还想在我的 AngularJS 博客中包含 Disqus。我发现现有的解决方案有点笨拙,所以我编写了自己的指令:
.directive('dirDisqus', function($window) {
return {
restrict: 'E',
scope: {
disqus_shortname: '@disqusShortname',
disqus_identifier: '@disqusIdentifier',
disqus_title: '@disqusTitle',
disqus_url: '@disqusUrl',
disqus_category_id: '@disqusCategoryId',
disqus_disable_mobile: '@disqusDisableMobile',
readyToBind: "@"
},
template: '<div id="disqus_thread"></div><a href="http://disqus.com" class="dsq-brlink">comments powered by <span class="logo-disqus">Disqus</span></a>',
link: function(scope) {
scope.$watch("readyToBind", function(isReady) {
// If the directive has been called without the 'ready-to-bind' attribute, we
// set the default to "true" so that Disqus will be loaded straight away.
if ( !angular.isDefined( isReady ) ) {
isReady = "true";
}
if (scope.$eval(isReady)) {
// put the config variables into separate global vars so that the Disqus script can see them
$window.disqus_shortname = scope.disqus_shortname;
$window.disqus_identifier = scope.disqus_identifier;
$window.disqus_title = scope.disqus_title;
$window.disqus_url = scope.disqus_url;
$window.disqus_category_id = scope.disqus_category_id;
$window.disqus_disable_mobile = scope.disqus_disable_mobile;
// get the remote Disqus script and insert it into the DOM
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
dsq.src = '//' + scope.disqus_shortname + '.disqus.com/embed.js';
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
}
});
}
};
});
优势
我认为,这种方法的主要优点是它使事情变得简单。在您的应用程序中注册指令后,您无需编写任何 JavaScript 或在 JavaScript 中设置任何配置值。所有配置都是通过在指令标签中传递属性来处理的,如下所示:
<dir-disqus disqus-shortname="YOUR_DISQUS_SHORTNAME"
disqus-identifier="{{ article.id }}"
disqus-title="{{ article.title }}"
...>
</dir-disqus>
此外,您无需更改 index.html 文件以包含 Disqus .js 文件 - 该指令将在准备就绪时动态加载它。这意味着所有额外的 .js 只会在那些实际使用 Disqus 指令的页面上加载。
您可以查看完整的源代码和文档 here on GitHub
警告
以上仅当您的站点处于 HTML5Mode 时才能正常工作,即不在您的 URL 中使用“#”。我正在 GitHub 上更新代码,因此该指令将在不使用 HTML5Mode 时起作用,但请注意,您必须将 hashPrefix 设置为“!”制作“hashbang”网址 - 例如
www.mysite.com/#!/page/123
.这是 Disqus 施加的限制 - 参见 http://help.disqus.com/customer/portal/articles/472107-using-disqus-on-ajax-sites
关于unit-testing - 在单页应用程序中使用 Disqus 的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15823047/