5

I'm trying to write my KO templates in a certain manner, and it seems to be causing issues with Knockout, which stops updating the view. I wish to avoid too many explicit dependencies in my views as possible, so when I'm writing a template for adding to an files attachments list, I thought I could make use of the $data variable:

<script id="attachments-template" type="text/html">
    <input type="button" data-bind="attachments: $data" value="add">
</script>

And the template binding:

<div data-bind="template: {name: 'button-add-data', data: attachments}"></div>

This keeps the actual property mapped in the usage site, instead of off in random templates. The attachments binding handler in my actual case wraps the jQuery fileupload plugin, but just calling push(i++) shows the issue anyway.

var i = 0;
ko.bindingHandlers.attachments = {
    init: function(element, valueAccessor) {
        var files = valueAccessor();
        $(element).click(function() {
            files.push(i++);
        });
    }
};

var list = ko.observableArray();
var model= {
    attachments: list
};

A fiddle which shows this, using KO 2.2.0: http://jsfiddle.net/stofte/sWGkJ/ The fiddle also shows that binding against an explicit property works fine.

Obviously there's alot of stuff on Google and SO on KO and binding contexts, but I can't find anything on the usage of $data in binding handlers, I'm not sure what KO law I'm breaking with my usage of $data, but seems like it would make good sense to be able to do what I want?

4

1 に答える 1

1

ノックアウトは、テンプレートバインディングobservableArrayのパラメーターに an を渡すことを正確に期待していないようです。data通常、それが a のforeach目的です。通常のオブジェクトが正しく動作することを期待しているようですdata(引用が必要です。このように動作するように見えるという事実以外のドキュメントは見つかりませんでした)。

あなたが持っているのと同じ JS コードを使用すると、最も簡単な解決策は、監視可能な配列をテンプレート バインディングで直接ラップすることのようです。

<script id="button-add-data" type="text/html">
    isObservable: <span data-bind="text: ko.isObservable(items)"></span><br>
    toJSON: <span data-bind="text: ko.toJSON(items)"></span><br>
    <input type="button" data-bind="attachments: items" value="doesnt update">
</script>
<div data-bind="template: {name: 'button-add-data', data: { items: attachments }}"></div>

または、テンプレート bindingHandler をオーバーライドし、渡すことができる新しいパラメーターを作成して、この同様の動作を簡素化することもできます。リンク:バインディングハンドラをオーバーライドするノックアウトjs

于 2012-12-25T07:49:31.590 に答える