淘汰赛 - 将值写入 ko.computed
Posted
技术标签:
【中文标题】淘汰赛 - 将值写入 ko.computed【英文标题】:Knockout - write a value to a ko.computed 【发布时间】:2014-07-26 13:44:51 【问题描述】:我在 Knockout 中构建了一个非常注重数据/数字的应用。我目前收到错误:
未捕获的错误:无法将值写入 ko.computed,除非您 指定一个“写”选项。如果您想读取当前值,请不要 传递任何参数。
当我的自定义 bindingHandler(将数字格式化为“大”形式,即 123,345,678,987)尝试写回显示计算函数值的原始输入时,就会发生这种情况。
输入元素中显示的值:
self.value = ko.computed(function()
return self.chosenAge().population; // 'fetched' from an array.
);
绑定处理程序:
ko.bindingHandlers.largeNumber =
init: function(element, valueAccessor)
numberInit(element);
var value = valueAccessor();
var interceptor = ko.computed(
read: function()
// inject number formatting
return numeral(ko.unwrap(value)).format('0,0');
,
write: function(newValue)
// remove formatting when writing a new value
value(numeral().unformat(newValue));
);
// display new value in target element
if(element.tagName.toLowerCase() == 'input' )
ko.applyBindingsToNode(element,
value: interceptor
);
else
ko.applyBindingsToNode(element,
text: interceptor
);
;
【问题讨论】:
你真的想回信给你的value
计算吗?或者你想更新population
?
基本上,您可以告诉输入字段中显示的值是从 selectedAge 数组中获取的。我正在尝试获取它,因此如果您单击该输入元素,您可以使用largeNumber
格式输入您自己的自定义群体
【参考方案1】:
您需要在您的 ko.computed 函数中指定一个“写入”选项。请参阅documentation on computed observables。您的绑定处理程序与您的值未能更新无关。您的计算结果应如下所示:
self.value = ko.computed(
read: function ()
return self.chosenAge().population; // 'fetched' from an array.
,
write: function (value)
//update your self.chosenAge().population value here
,
owner: self
);
希望这会有所帮助。
【讨论】:
是的,我最初尝试过这个,我遇到的问题是把它写回去?不知道该怎么做 如果没有关于您的chosenAge
对象的更多信息,我真的无法给您一个好的答案,您能否更新您的帖子并提供更多信息?
我认为你的代码不正确,ko.computed
里面应该是一个对象,而不是一个函数。链接也过时了,新链接是knockoutjs.com/documentation/computed-writable.html
这甚至不是正确的javascript【参考方案2】:
就我个人而言,我会在extender
中捕获您的格式实现。
定义一个扩展,使用computed
格式化程序包装可观察的数据:
ko.extenders.largeNumber = function (target, option)
var formatter = ko.computed(
read: function()
var formatted = target().toString().replace(/\B(?=(\d3)+(?!\d))/g, ",");
return formatted;
,
write: function(nv)
var numeric = nv.replace(/,/g,"");
target(numeric);
console.log("View model now contains " + target())
)
return formatter;
;
然后创建一个使用扩展的可观察对象:(我已经将它包装在构造函数中)
function createExtendedObs(initialValue)
return ko.observable(initialValue).extend(
largeNumber:
viewModel: self
);
此外,我会让我的 observable 成为数据对象中的 population
属性,它代表 chosenAge
name: "Bronze",
population: createExtendedObs(10000)
这不是必需的。 如果您希望将总体存储在另一个 observable 中,我将扩展器设置为通过 options
参数访问 viewModel。因此,您将以这种方式访问另一个可观察对象。如果要计算“其他”可观察对象,那么您需要指定 write
函数(如另一个答案中所述),这是您遇到的问题的根源。另一种选择是将subscribe
设置为chosenAge
并设置从订阅中可观察到的“其他”人口。
直接使用 data 属性,我可以按如下方式绑定到它,
<div data-bind='with: chosenAge'>
<input data-bind='value: population'></input>
</div>
查看my fiddle 了解完整设置。
编辑
刚刚查看了一条关于希望输入“带有”格式的值的评论。每次计算接收到一个新值时,该字段将被格式化。默认情况下,这将是焦点丢失。如果要在提供输入时对其进行修改,则需要提供 valueUpdate
绑定参数。 由于该字段是动态操作的,这将导致插入符号定位问题。您需要相应地管理插入符号的位置。
<input data-bind='value: population, valueUpdate: "afterkeydown"'></input>
【讨论】:
以上是关于淘汰赛 - 将值写入 ko.computed的主要内容,如果未能解决你的问题,请参考以下文章