4

リストからアイテムを削除しようとしています。マッピングプラグインでノックアウト.jsを使用しています。私のコードは次のようになります。

Jsonにシリアライズ

@{ var jsonData = new HtmlString(new JavaScriptSerializer().Serialize(Model));}

テンプレート

<script type="text/html" id="imgsList">
    {{each model.Imgs}}
        <div style="float:left; margin: 10px 10px 10px 0;">
            <div><a href="${Filename}"><img src="${Filename}" style="width:100px;"></img></a></div>
            <div data-bind="click: deleteImage">Delete</div>
        </div>
    {{/each}}
</script>

KO JavaScript

<script type="text/javascript">
     $(function() {
        //KO Setup
        var viewModel = { 
            "model": ko.mapping.fromJS(@jsonData),
            "deleteImage" : function(item) {alert(item.Filename + ' deleted.');}
        }

        ko.applyBindings(viewModel);
    });
</script>

HTML

<div data-bind="template: 'imgsList'"></div>

質問

すべてが期待どおりに機能します。ただし、ボタン項目をクリックすると、画像のリストが削除ボタンとともに表示されます。ファイル名は未定義です。考え?

編集: KNockout.js マニュアルから引用: 「ハンドラーを呼び出すと、Knockout は現在のモデル値を最初のパラメーターとして提供します。これは、コレクション内の各アイテムの UI をレンダリングしている場合に特に役立ちます。どのアイテムの UI がクリックされたかがわかります。」

私が期待している Img オブジェクトを取得していないようです。何が返ってくるかわからない!

4

2 に答える 2

7

ここにこれを行う方法の例があることに気付きました:

http://blog.stevensanderson.com/2011/12/21/knockout-2-0-0-released/

スティーブがリストからアイテムを削除する例を示している4. よりクリーンなイベント処理セクションを確認してください。

<h3>Products</h3>

<ul data-bind="foreach: products">
    <li>
        <strong data-bind="text: name"></strong>
        <button data-bind="click: $parent.removeProduct">Delete</button>
    </li>
</ul>

Javascript:

    function appViewModel() {
        var self = this;
        self.products = ko.observableArray([
            { name: "XBox" },
            { name: "PlayStation" },
            { name: "Banana" },
            { name: "Wii" }
        ]);

        self.removeProduct = function(product) {
            self.products.remove(product);   
        }
    };

ko.applyBindings(new appViewModel());

ただし、上記の例は最新リリースである KnockoutJS 2.0 用であることを考慮してください。

于 2012-01-02T23:35:32.713 に答える
6

jQuery テンプレートで {{each}} 構文を使用する場合、データ コンテキストは、テンプレート全体がバインドされているものです。あなたの場合、それはビューモデル全体です。

いくつかのオプション:

1-現在のコードを使用して、「取得」しているアイテムを次のような関数に渡すことができます(http://jsfiddle.net/rniemeyer/qB9tp/1/):

<div data-bind="click: function() { $root.deleteImage($value); }">Delete</div>

ただし、データバインドで無名関数を使用するのはかなり醜いです。より良いオプションがあります。

2- jQuery テンプレートで動作し、( http://jsfiddle.net/rniemeyer/qB9tp/2/ )foreachのような {{each}} よりも効率的なテンプレート バインディングのパラメーターを使用できます。

<script type="text/html" id="imgsList">
    <div style="float:left; margin: 10px 10px 10px 0;">
        <div>
            <a href="${Filename}">${Filename}</a>
        </div>
        <div data-bind="click: $root.deleteImage">Delete</div>
    </div>
</script>

<div data-bind="template: { name: 'imgsList', foreach: model.Imgs }"></div>

現在、テンプレートのコンテキストは個々の画像オブジェクトであり、呼び出し$root.deleteImageはそれを最初の引数として渡します。

3- jQuery テンプレート プラグインは廃止され、Knockout はネイティブ テンプレートをサポートするようになったため、jQuery テンプレート プラグインへの依存を削除することを選択することをお勧めします。http://jsfiddle.net/rniemeyer/qB9tp/3/のような名前付きテンプレートを引き続き使用することもできます (jQuery テンプレート構文をデータバインド属性に置き換えるだけで済みます)。foreachまたは、テンプレートを削除してコントロールを使用することもできます。次のようなフロー バインディング: http://jsfiddle.net/rniemeyer/qB9tp/4/

<div data-bind="foreach: model.Imgs">
    <div style="float:left; margin: 10px 10px 10px 0;">
        <div>
            <a data-bind="text: Filename, attr: { href: Filename }"></a>
        </div>
        <div data-bind="click: $root.deleteImage">Delete</div>
    </div>
</div>

4-私はオプション#3を好みますが、イベント委任を使用して、次のような「ライブ」ハンドラーをアタッチすることもできます:http://jsfiddle.net/rniemeyer/qB9tp/5/

$("#main").on("click", ".del", function() {
   var data = ko.dataFor(this);
   viewModel.deleteImage(data); 
});

clickこれは、(グリッドのように) バインドを介して多数の同じハンドラーをアタッチする場合に特に役立ちます。

于 2012-01-03T03:42:22.783 に答える