1

您好,我在扩展 observableArray 的扩展器“paged”中有一个 KnockoutJs 计算的 observable ItemCountText。observableArray 是 Products。

这按预期工作,给了我“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

在我仍然无法访问扩展器属性的自定义绑定实验失败后,我发现了一个相当简单的解决方案,即声明一种指向“分页”扩展器的指针

Products 和 Changes 都是 observableArrays 扩展名为 'paged'

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”的自定义绑定可能会接受扩展名,从而允许

于 2013-10-18T12:45:45.730 回答
0

问题是在您的数据实际位于该 ItemCountText 之前,您的 observable 已创建并绑定到视图 -

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>

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

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

于 2013-10-17T18:23:37.903 回答