knockoutjs extender可观察到的未知通过绑定

时间:2013-10-17 18:18:36

标签: knockout.js

你好我在扩展器“paged”中有一个KnockoutJs计算的可观察ItemCountText,它扩展了observableArray。 observableArray是产品。

这按预期工作,给我“32个产品”(32,48,无论数字是什么,加上“产品”或我传入扩展器设置的任何文字)

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

..但是这个

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

...因错误而导致错误:无法解析绑定。消息:ReferenceError:未定义ItemCountText;绑定值:text:ItemCountText

这里可能存在的问题是,虽然定义了“Products.ItemCountText”绑定,导致扩展程序的计算可观察ItemCountText不在“with:Products”中定义?感觉好像'ko with:'的绑定机制无法找到“扩展器”的方式。

这是展示这个问题的小提琴。为了避免分心,分页扩展程序会删除与问题无关的所有内容。

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

要体验上述问题,请取消注释小提琴的HTML第14行并运行

Knockout是版本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);

2 个答案:

答案 0 :(得分:0)

问题是你的observable是在数据实际存在于ItemCountText之前创建并绑定到视图的 -

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

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

附加$ data。在前面,它告诉Knockout,如果它有一个值,只绑定它,基本上推迟绑定,直到ItemCountText有一个值。

修改更新

你的with:binding忽略了扩展属性,因为你将上下文绑定到数组的值,而不包括那些扩展属性。

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

当您绑定:products时,它几乎与使用observable的值绑定相同 - 该对象的任何其他属性都不属于可观察值,将被忽略。

如果你必须使用绑定使用$ parent.Products在容器中绑定,请将其重新导入 - http://jsfiddle.net/J4Nd2/4/

答案 1 :(得分:0)

在自定义绑定失败的实验中,我仍无法访问扩展器的属性,我发现了一个相当简单的解决方案,声明了一个指向'paged'扩展器的指针

产品和更改都是使用名为“paged”的扩展名扩展的observableArrays

self.Products.Paged = ko.computed(function() {
    return self.Products['extend']('paged');
});

self.Changes.Paged = ko.computed(function() {
    return self.Changes['extend']('paged');
});

现在我可以使用无容器'with'绑定来包含我的_Pager视图,该视图使用名为'paged'的扩展程序的属性,现在任何由'paged'扩展的内容都可以绑定到我的_Pager视图

<!-- ko with: Products.Paged -->
    @Html.Partial("_Pager",Model)
<!-- /ko -->

<!-- ko with: Changes.Paged -->
    @Html.Partial("_Pager",Model)
<!-- /ko -->

现在我已经发现了这个,我敢打赌可以编写一个自定义绑定来进行指向,这样就不需要将指针添加到扩展的所有内容中。相反,名为“withExtension”的自定义绑定可能接受扩展名,允许