13

単一ページのアプリケーションで 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
    };
}]);
4

3 に答える 3

4

Disqus については何も知りませんが、AngularJS ドキュメントのソース コードによると:

ロード関数を 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('');
}
于 2013-04-26T01:02:21.057 に答える
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();
  });

});
于 2013-04-26T10:23:40.977 に答える