13

什么是单页的应用程序使用Disqus最好的方法? 我看到角度js文档已成功实现它。什么是单页的应用程序使用Disqus最好的方法?

目前我们的做法看起来是这样的在我们的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 
    }; 
}]); 

回答

7

我也想包括我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,即不使用“#”在你的网址只能正常工作。我更新GitHub上的代码,使该指令将不使用HTML5Mode时工作,但被警告,你必须设置的“!”一个hashPrefix制作“hashbang”网址 - 例如www.mysite.com/#!/page/123。这是由Disqus强加的限制 - 见http://help.disqus.com/customer/portal/articles/472107-using-disqus-on-ajax-sites

+0

我怀疑这不是您的指令问题,但无论如何,每个评论都会在每个评论部分的每个页面上呈现我的应用。 我传递唯一标识符作为属性,并使用ng-bind-ready,因为我使用异步数据加载。我也检查过这个指令,看看我的标识符。 我使用没有HTML5模式的角路由,没有任何哈希前缀(只有#号)。 你有什么想法如何解决它?我在你的指令github页面上添加了一个问题。 – 2014-02-24 23:35:34

+0

好的,我们可以在GitHub问题跟踪器上继续此操作。对于任何阅读谁有同样的问题,这里的链接:[https://github.com/michaelbromley/angularUtils/issues/1](https://github.com/michaelbromley/angularUtils/issues/1) – 2014-02-25 07:49:27

+0

显示错误:'TypeError:无法读取未定义的属性'disqus_shortname' – marukobotto 2016-10-01 14:57:04

4

我一无所知Disqus,但根据AngularJS文档source code

它们所连接的负载功能afterPartialLoaded:

$scope.afterPartialLoaded = function() { 
    var currentPageId = $location.path(); 
    $scope.partialTitle = $scope.currentPage.shortName; 
    $window._gaq.push(['_trackPageview', currentPageId]); 
    loadDisqus(currentPageId); 
}; 

然后,他们只需将HTML添加到页面:

function loadDisqus(currentPageId) { 
    // http://docs.disqus.com/help/2/ 
    window.disqus_shortname = 'angularjs-next'; 
    window.disqus_identifier = currentPageId; 
    window.disqus_url = 'http://docs.angularjs.org' + currentPageId; 

    // http://docs.disqus.com/developers/universal/ 
    (function() { 
    var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true; 
    dsq.src = 'http://angularjs.disqus.com/embed.js'; 
    (document.getElementsByTagName('head')[0] || 
     document.getElementsByTagName('body')[0]).appendChild(dsq); 
    })(); 

    angular.element(document.getElementById('disqus_thread')).html(''); 
} 
4

这就是我们如何解决它的。

我们的index.html的机身装载DISQUS,并重置它,每当有使用它一个指令。

指令:

'use strict'; 

angular.module('fooApp.directives') 
    .directive('disqusComponent',['$window', '$log', function($window, $log) { 

    var _initDisqus = function _initDisqus(scope) 
    { 
     if($window.DISQUS) { 
       $window.DISQUS.reset({ 
        reload: true, 
        config: function() { 
         this.page.identifier = scope.threadId; 
         this.disqus_container_id = 'disqus_thread'; 
        } 
       }); 
     } 
     else 
     { 
      $log.error('window.DISQUS did not exist before directive was loaded.'); 
     } 
    } 

    var _linkFn = function link(scope, element, attrs) { 
      element.html('<div id="disqus_thread"></div>'); 
      _initDisqus(scope); 
     } 


    return { 
     replace: true, 
     template: 'false', 
     scope: { 
      threadId: '@' 
     }, 
     link: _linkFn 
    }; 
}]); 

这是它如何进行测试:

'use strict'; 

describe('Directive: Disqus', function() { 

    var element, $window, $rootScope, $compile; 

    beforeEach(function() { 
    module('fooApp.directives', function($provide) { 
     $provide.decorator('$window', function($delegate) { 

      $delegate.DISQUS = { 
       reset: jasmine.createSpy() 
      }; 

      return $delegate; 
     }); 
    }); 

    inject(function(_$rootScope_, _$compile_, _$window_) { 
     $window = _$window_; 
     $rootScope = _$rootScope_; 
     $compile = _$compile_; 
    });  

    }); 


    it('should place a div with id disqus_thread in DOM', function() { 
    element = angular.element('<disqus-component></disqus-component>'); 
    element = $compile(element)($rootScope); 
    expect(element.html()).toBe('<div id="disqus_thread"></div>'); 
    }); 

    it('should do a call to DISQUS.reset on load', function() { 
    element = angular.element('<disqus-component thread-id="TESTTHREAD"></disqus-component>'); 
    element = $compile(element)($rootScope); 

    var resetFn = $window.DISQUS.reset; 

    expect(resetFn).toHaveBeenCalled(); 
    }); 

}); 
+0

确定this.disqus_container_id存在?它在文档中的任何地方都没有提及。此外,是否存在this.disqus_category_id?不应该是this.page.container_id? – CMCDragonkai 2013-08-20 13:58:39

相关问题