你好我在扩展器“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:'的绑定机制无法找到“扩展器”的方式。
这是展示这个问题的小提琴。为了避免分心,分页扩展程序会删除与问题无关的所有内容。
要体验上述问题,请取消注释小提琴的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);
答案 0 :(得分:0)
问题是你的observable是在数据实际存在于ItemCountText之前创建并绑定到视图的 -
<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”的自定义绑定可能接受扩展名,允许