2017-06-30 9 views
2

支援フィドル結合カスタムのコールバックをオーバーライド:私は2つの構成要素を有し、それぞれがそのテンプレートに(button)カスタム結合噴射https://jsfiddle.net/lezhnev_dmitriy/5Lvq1nra/複数のコンポーネントインスタンス

$(function(){ 
 

 
// when DOM ready 
 

 
ko.bindingHandlers.button = { 
 
    init: function (element, valueAccessor, allBindings) { 
 
        this.onClick = valueAccessor(); 
 
        $(element).html('<button data-bind="click: onClick">Click</button>'); 
 
       }, 
 
    update: function (element, valueAccessor, allBindings) { 
 
       }, 
 
}; 
 

 
ko.components.register('comp1', { 
 
\t template: '<div>component instance <span data-bind="text: instance_id"></span> <span data-bind="button: handleClick"></span></div>', 
 
    viewModel: function() { 
 
    var self = this; 
 
    self.instance_id = ko.observable(Math.round(Math.random() * 1000)); // debug purpose 
 

 
    self.handleClick = function() { 
 
     alert('clicked at ' + self.instance_id()); 
 
    }.bind(this); // very interesting hint! 
 
    } 
 
}); 
 

 
ko.applyBindings(); 
 

 

 
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script> 
 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> 
 
<comp1></comp1> 
 
<comp1></comp1>

を。次に、そのバインディングにコールバックをアタッチします。 最後のバインディングのみが機能します(両方のボタンが最後のコンポーネントインスタンスを介して処理されるようになりました)。

何か不足していますか?

UPDATE: 私はこのコードは実際に私の意見では

ko.bindingHandlers.button = { 
 
       init: function (element, valueAccessor, allBindings) { 
 
        var self = this; 
 
        self.onClick = valueAccessor(); 
 
        $(element).html('<button>Click</button>'); 
 
        $('button', element).click(self.onClick); 
 
       }, 
 
       update: function (element, valueAccessor, allBindings, viewModel_deprecated, bindingContext) { 
 
        var self = this; 
 

 
       }, 
 
      }; 
 

 
      ko.components.register('comp1', { 
 
       template: '<div>component instance <span data-bind="text: instance_id"></span> <span data-bind="button: handleClick"></span></div>', 
 
       viewModel: function() { 
 
        var self = this; 
 
        self.instance_id = ko.observable(Math.round(Math.random() * 1000)); // debug purpose 
 

 
        self.handleClick = function() { 
 
         console.log('clicked at ' + self.instance_id()); 
 
        }.bind(this); // very interesting hint! 
 
       } 
 
      }); 
 
      
 
ko.applyBindings();
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script> 
 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> 
 

 
<comp1></comp1> 
 
<comp1></comp1>

+0

私はこの回避策を見つけました。https://github.com/knockout/knockout/issues/2263 –

+0

createViewModel関数を試してみましたが、私はそれを使って0の問題を抱えていました。 – Shadowfox

+1

自分自身も同じ問題を試しました。私は、問題はbindingHandlerのコードでDOM要素を追加することによると思います。あなたは私が推測するようにテンプレートを使用するはずです。 Fiddle:https://jsfiddle.net/5Lvq1nra/2/ – Shadowfox

答えて

1

を動作することが判明、あなたはbindingHandlerのコード内のDOMノードを変更することになっていません。 私たちはその理由のためにテンプレートを持っています。

<script id="buttonTemplate" type="text/html"> 
    <button data-bind="click: handleClick">Click</button> 
</script>  

template: '<div>component instance <span data-bind="text: instance_id"></span> <span data-bind="template: {name: \'buttonTemplate\', data: $data }"></span></div>', 

私はあなたのフィドルを更新しました:https://jsfiddle.net/5Lvq1nra/2/

編集:テンプレートのデータプロパティに$データを渡すと、本当にちょうどあなたのようにオブジェクトを渡すことができます表示するには、(デフォルト)は必要ありませんモデル。

+0

テンプレートが私の場合に合わないかもしれないと思う。とにかく、私が何を持っているか教えてあげてください。もっとアドバイスできますか? 私は複数のページを持つことができるSPAを持っています。各ページは、ノックアウトコンポーネント(上部の検索フィルタと下部の検索結果)によって強化されています。 カスタムバインディングを使用した検索フィルタ。 コンポーネントは検索ウィジェットをテンプレートに挿入し、検索が開始されたときに通知を受け取るようにコールバックを渡します。 ウィジェット自体は、カスタムhtmlやDOMイベントを使用したカスタムバインディングの候補になるほど複雑です。 あなたには意味がありますか? –

関連する問題