0

私は Knockout と D3 (Data Driven Documents) の初心者です。私がやろうとしているのは、D3 に表示させる JS オブジェクトの配列を作成することです。現在、HTML の span タグにいくつかの単語を表示するだけです。私がやろうとしているのは、表示される名前を KO オブザーバブルにすることです。さらに下の行 (date[0].name 行) を変更すると、ビューはそれらの変更を取得します。なんらかの理由で、最後の行は効果がないようです。HTML を生成しているときに何かが欠けていて、KO が変更する正しい場所を見つける方法がわからないという理論を立てています。d3.select チェーンの最後に「attr(x, y)」呼び出しを追加して、データ バインド属性を追加しようとしましたが、KO にはそれらが一意である必要があると思います (ただし、よくわかりません)。どんな助けでも大歓迎です。

var data = [
        { "id": "1", "name": ko.observable("alpha"), ...
        { "id": "2", "name": ko.observable("bravo"), ...
        { "id": "3", "name": ko.observable("delta"), ...
];

ko.applyBindings(data);

d3.select("body").selectAll("span")
.data(data)
.enter()
.append("span")
.text(
    function (d) {
        return d.name();
    }
);  

data[0].name('october');
4

1 に答える 1

1

Knockout を d3 と連携させたい場合は、作成する個々の要素にそれぞれノックアウト バインディングを適用する必要があります。

var data = [
    { "id": "1", "name": ko.observable("alpha") },
    { "id": "2", "name": ko.observable("bravo") },
    { "id": "3", "name": ko.observable("delta") }
];

d3.select("body").selectAll("span")
    .data(data)
    .enter()
    .append("span")
    .attr("data-bind", "text: name") // Applies the data binding attribute
    .each(function (d) {
        ko.applyBindings(d, this); // Sets up Knockout to work with the node
    });

data[0].name('october');

これらのバインディングを適用する必要があるのは 1 回だけです。ノードを変更しても、データ バインディングは引き続き適用されます。実際、既存のノードにバインディングを再適用する場合は、最初に を呼び出しko.cleanNode()て最初のバインディングを削除する必要があります。

バインディング コンテキストが何であれ、ビュー モデルからこのデータを取得する場合は、次のようなものを使用ko.dataFor()して、親要素でバインディングを取得します。

var data = ko.dataFor(d3.select("#parent-to-attach-to").node());

またはバインディングに明示的にサブスクライブします。

viewModel.observableIWantToTrack.subscribe(function(newValue) {
    // your d3 update code here, using newValue
}

または、それを呼び出すバインディング ハンドラーを作成します。

ko.bindingHandler.whateverYouWantToCallYourHandler = {
    init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
       // any initialization logic you need
    },
    update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
       // where you perform your actual updates
    }
}

状況に最も適したソリューションを使用してください。

もう 1 つ注意: バインディングは再評価されないため、 を呼び出す必要がありますko.applyBindings()ifこれは、やなどの通常のバインドではおそらく問題withありませんが、監視する必要があります。それらが許容されないのはforeachバインディングです。データ バインドされた d3 要素を挿入した後に foreach バインディングを評価しようとすると、配置した要素が Knockout によって複合され、多くの問題が発生します。foreachd3 のネイティブ データ結合動作に、ノックアウトの通常の動作を許可するのが最善です。

于 2016-01-16T00:14:34.237 に答える