グローバルD3オブジェクトだけを使用するディレクティブを見てきました。また、グローバルD3オブジェクトをサービスに戻すだけで挿入するディレクティブも見てきました。 D3スクリプトを追加し、D3オブジェクトを提供するスクリプトのロード時に解決される約束を返します。D3をAngularRJSに挿入するための適切な規約
注射可能なサービスでこれを使用すると、最も意味があるように見えます(例1と2を参照)。しかし、どちらの方が良いか分かりません。例2では、D3がコードを実行する前にロードされていることが保証されますが、他の人のようには見えません。それ以外の場合は、サービス内でディレクティブ全体をラップする必要があります。d3
と生成されたsvg
オブジェクトスコープまたは未定義である可能性が高い(例2を参照)が、私はいつも最初の解決と考えている、少なくともコンパイルの約束、例を参照してください。3.
例1:サービスは
.factory('D3Service', [,
function() {
// Declare locals or other D3.js
// specific configurations here.
return d3;
}]);
D3グローバルオブジェクトを渡す例2:D3スクリプトをDOMに追加して約束してくれるサービス
.factory('D3Service', ['$window', '$document', '$q', '$rootScope',
function ($window, $document, $q, $rootScope) {
var defer = $q.defer();
var scriptTag = $document[0].createElement('script');
scriptTag.type = 'text/javascript';
scriptTag.src = 'https://d3js.org/d3.v3.min.js';
scriptTag.async = true;
scriptTag.onreadystatechange = function() {
if (this.readyState == 'complete') {
onScriptLoad();
}
}
scriptTag.onload = onScriptLoad;
var script = $document[0].getElementsByTagName('body')[0];
script.appendChild(scriptTag);
//---
// PUBLIC API
//---
return {
d3: function() {
return defer.promise;
}
};
//---
// PRIVATE METHODS.
//---
// Load D3 in the browser
function onScriptLoad() {
$rootScope.$apply(function() {
defer.resolve($window.d3);
});
}
}]);
例3:SVGを追加するコンパイルを使用することに直面したとき、私は同様の質問があったSVGは、リンクで利用可能ですが、少なくとも、コンパイルの約束は、常に最初
// Perform DOM and template manipulations
function compile ($element, $attrs, $transclude) {
var svg;
// Callback provides raw D3 object
D3Service.d3().then(function (d3) {
// Create a responsive SVG root element
svg = d3.select($element[0])
.append('svg')
.style('width', '100%');
});
// Return the link function
return function($scope, $element, $attrs) {
// Is svg undefined?
// Maybe? so have to wrap everything again in service
D3Service.d3().then(function (d3) {
function render() {
// d3 and svg guaranteed to be available, but code gets really ugly looking and untestable
}
});
function render() {
// d3 and svg have to be passed in as they may not be available, but code is cleaner
}
};
}
うん。 d3.jsがウィンドウスコープ内に 'd3'を置く以外に何もしない限り、最終的に存在するかどうかをチェックするための' $ interval'の約束以上のものはありません。 [IE8で、とにかく] – Brian
こんにちは@ブライアンので、各グラフのディレクティブの 'リンク'は$間隔の約束を待ってからD3のグローバル参照を使用しますか?解決策のように思えるかもしれませんが、DRYerでなければならないかもしれません... – mtpultz
私は "d3が定義されていない場合、d3をロードして待ちます。誰かがIE8を含むブラウザのためのより良い解決策を持っているなら、@ me! – Brian