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

相關問題