1

カスタム コンポーネントと Knockout 内のカスタム バインディングの両方を使用して、小さなビジュアライゼーションをレンダリングしようとしています。私はこれを機能させましたが、ソリューションが理想的ではないことに気付きました。私のカスタム バインディングは、トランジションを使用してデータの変更を処理することになっています。

ここに画像の説明を入力

新しいアイテムが表示された場合、たとえばE、それをトランジションさせたいと思います。また、バインディングが変更されるたびに、各円の周りの緑色のストロークを更新する必要があります。

私の問題は、context以下のコードでバインディングが更新されると、バインディング全体が再初期化されるように見えることです。context下のノックアウトは前の DOM を削除し、ロット全体を再レンダリングしていると思います。これにより、各円が成長し、新しいアイテムのアニメーションがトリガーされます。

ko.components.register("context", {
    // Assume that the view model given to us is already observable, having had a ko.mapping.fromJS() applied or similar
    viewModel: function (vm) {
        this.context = vm;
    },
    template: '<div class="card context-card" data-bind="contextViz: context">\
                <!-- ko if: context && context.types.length === 0 -->\
                    <div>Please make a selection to view contextual information here.</div>\
                <!-- /ko -->\
               </div>\
               '
});

これを防ぐために何かできることはないかと考えています。基本的に、古いバインディングを更新したいのですcontextが、そうする方法があるかどうかはわかりません。

説明するためにコード スニペットを追加しました。ここでinit calledは、更新が発生するたびにログが記録されます。これを 1 回だけログに記録し、update called何度もログに記録するようにします。

var count = 0;

ko.bindingHandlers.contextViz = {
    init: function() {
        console.log("init called");
    },
    update: function() {
        console.log("update called");
    }
};

ko.components.register("context", {
    viewModel: function (vm) {
        this.context = vm;
    },
    template: '<div class="card context-card" data-bind="contextViz: context">'
});

var vm = {
   context: ko.observable({ count: count })
};

ko.applyBindings(vm);

setInterval(function() {
  vm.context({ count: count + 1 });  
}, 1000);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div data-bind="component: { name: 'context', params: $root.context }"></div>

4

1 に答える 1