1

こんにちは、observableArray を拡張する「ページ化」されたエクステンダに、KnockoutJs によって計算された観測可能な ItemCountText があります。observableArray は製品です。

これは期待どおりに機能し、「32 製品」(32、48、その数に加えて「製品」またはエクステンダーの設定に渡したテキスト) が表示されます。

<span data-bind="text:Products.ItemCountText"></span> 

.. でもこれは

<!-- ko with: Products -->
<span data-bind="text:ItemCountText"></span>
<!-- /ko -->

...エラーで壊れています: バインディングを解析できません。メッセージ: ReferenceError: ItemCountText が定義されていません。バインディング値: テキスト: ItemCountText

「Products.ItemCountText」バインディングが定義されているにもかかわらず、エクステンダーの計算された監視可能な ItemCountText が「with: Products」内で定義されない原因となる問題は何ですか? 「ko with:」のバインド メカニズムがエクステンダーに「入る」ことができないように感じます。

これは、問題を示すフィドルです。注意散漫を避けるために、ページ エクステンダーでは、問題に関係のないものはすべて切り取られています。

http://jsfiddle.net/J4Nd2/1/

上記の問題を経験するには、フィドルの HTML 行 14 のコメントを外して実行します

ノックアウトはバージョン 2.2.1 です

JsFiddle の HTML は次のとおりです。

    <div id="bindMe">
    <span data-bind='text: Yay()'></span>
    <div data-bind="text: Products.ItemCountText"></div>
    <div><span data-bind="text: Products().length"></span> on this page</div>
    <!-- ko with: Products -->
        <ul>
            <!-- ko foreach: $data -->
                <li data-bind="text: $data"></li>
            <!-- /ko -->
        </ul>
    <!-- /ko -->
<span data-bind='text: Boo'></span>
    <!-- ko with: Products -->
<!--    <div data-bind="text: ItemCountText"></div>  -->
        <div><span data-bind="text: length"></span> on this page</div>
        <ul>
            <!-- ko foreach: $data -->
                <li data-bind="text: $data"></li>
            <!-- /ko -->
        </ul>
    <!-- /ko -->   
</div>

これがJsFiddleのJavascriptです

ko.extenders.paged = function (target, options) {
    // Settings
    var settings = $.extend({
        "itemcounttext": 'Counted Items'
    }, options);

    target.TotalRecords = ko.observable();
    target.ItemCountText =  ko.computed(function () {
        return target.TotalRecords() + " " + settings.itemcounttext;
    });

    return target;
};
/// -- End paging extender -- \\\

var ViewModel = function()  {
    var self = this;
    self.Yay = ko.observable("Hello World... Products.ItemCountText.. it works great");
self.Boo = ko.observable("But if HTML line 14 is uncommented, why does ItemCountText from extender broke using ko with?");
    self.Products = ko.observableArray([]).extend(
    {
        paged:
        {
            "itemcounttext": 'Products in total'
        }
    });
};

var myViewModel = new ViewModel();
ko.applyBindings(myViewModel, document.getElementById("bindMe"));

myViewModel.Products.push('prod a');
myViewModel.Products.push('prod b');
myViewModel.Products.push('prod c');
myViewModel.Products.TotalRecords(5);
4

2 に答える 2

0

問題は、データが実際にその ItemCountText に入る前に、オブザーバブルが作成され、ビューにバインドされることです -

http://jsfiddle.net/J4Nd2/2/

<div data-bind="text: $data.ItemCountText"></div>

$data を追加します。前面では、値がある場合にのみこれをバインドするように Knockout に指示し、基本的に ItemCountText が値を持つまでバインドを延期します。

更新を編集

あなたの with: バインディングは、拡張プロパティを含まない配列の値にコンテキストをバインドしているため、拡張プロパティを無視しています。

<!-- ko with: Products -->
<span data-bind="text: $data"></span>

製品とバインドする場合、オブザーバブルの値とのバインドとほぼ同じです。オブザーバブル値の一部ではないそのオブジェクトの他のプロパティは無視されます。

バインディングを使用してコンテナレス内でバインドする必要がある場合は、 $parent.Products を使用して元に戻します - http://jsfiddle.net/J4Nd2/4/

于 2013-10-17T18:23:37.903 に答える