Javascript 通过索引KnockoutJS写入的可观察数组
我无法通过特定索引写入可观察数组 JS HTML页面Javascript 通过索引KnockoutJS写入的可观察数组,javascript,knockout.js,frontend,Javascript,Knockout.js,Frontend,我无法通过特定索引写入可观察数组 JS HTML页面 <input type="number" data-bind="value: curNumber"> <button data-bind="click: addNumber">Add</button> 添加 我希望当我在输入上写“1”并单击“添加”按钮时,第一个索引值将在1上递增,但它对我不起作用 function AppViewModel() { this.curNumber = ko.ob
<input type="number" data-bind="value: curNumber">
<button data-bind="click: addNumber">Add</button>
添加
我希望当我在输入上写“1”并单击“添加”按钮时,第一个索引值将在1上递增,但它对我不起作用
function AppViewModel()
{
this.curNumber = ko.observable();
this.numbers = ko.observableArray([0,0,0,0,0,0,0,0,0]);
this.addNumber = function() {
this.numbers()[this.curNumber()]++;
this.numbers.valueHasMutated();
}
}
ko.applyBindings(new AppViewModel());
ko.observearray
包含一个香草Javascript数组作为值,因此需要使用this.numbers()[index]
提取Javascript香草,注意()
,打开ko.observearray值并返回该值,即Javascript数组
在代码中,您试图对ko.observearray本身进行数组索引:this.numbers[index]
最后,使用@Kenneth的答案,您需要让KnockoutJs知道,如果您的UI或其他观察对象要通过调用this.numbers
来响应您的addNumber
调用,那么ko.observearray已经发生了变化
最好在可观察的curNumber
上使用subscribe
来监听curNumber
的更改,subscribe
功能会在每次curNumber
更改时自动触发增量
function AppViewModel()
{
this.curNumber = ko.observable();
this.numbers = ko.observableArray([0,0,0,0,0,0,0,0,0]);
this.curNumber.subscribe(function(newValue) {
this.numbers()[newValue]++;
this.numbers.valueHasMutated();
});
}
如果它适合您的需要,下面是一个使用KnockoutJSsubscribe
和每次curNumber
更改的实现
function AppViewModel()
{
this.curNumber = ko.observable();
this.numbers = ko.observableArray([0,0,0,0,0,0,0,0,0]);
this.curNumber.subscribe(function(newValue) {
this.numbers()[newValue]++;
this.numbers.valueHasMutated();
});
}
现在您不需要调用addNumber
的额外步骤
下面只是对valueHasMutated的测试,我反复检查了提取Javascript数组和更新数组中的项目是否是KnockoutJs无法观察到的,在这种情况下,您必须调用valueHasMutated(),否则KnockoutJs将不会注意到您的数组增量
函数AppViewModel()
{
this.curNumber=ko.可观察(0);
this.numbers=ko.observearray([0,0,0,0,0,0,0]);
this.addNumber=函数(){
resetUI();
this.numbers()[this.curNumber()]++;
this.numbers.valueHasMutated();
}
this.addNumberWithoutHasValueMutated=函数(){
resetUI();
this.numbers()[this.curNumber()]++;
}
this.numbers.subscribe(函数(newValue){
$('#divStatus').html(“true”);
});
}
var viewModel=新的AppViewModel();
应用绑定(视图模型);
函数resetUI(){
$('#divStatus').html(“false”);
}
通过敲除观察阵列变化:
假的
这是"数字"()=
这个.curNumber()=
呼叫地址号码
调用addnumberwhithouthasvaluemutated
正如Brian在回答中所说,数组是可观察的,但数组中的值不是。如果要触发更新,必须通过在可观察对象上调用valueHasMutated
手动执行:
function AppViewModel()
{
this.curNumber = ko.observable("");
this.numbers = ko.observableArray([0,0,0,0,0,0,0,0,0]);
this.addNumber = function() {
var index = this.curNumber();
var arr = this.numbers();
arr[index] = arr[index] + 1;
this.numbers.valueHasMutated(); // This tells knockout the value has changed
}
}
ko.applyBindings(new AppViewModel());
使用此代码,检查小提琴: 您的代码:
this.numbers[this.curNumber]++
有几个问题:
问题1:
this.curNumber
是一个可观察值,必须将其作为函数调用,才能将值包装在其中
问题2
即使这样做,它仍然无法工作,因为从DOM获得的值是一个字符串,因此需要首先将其转换为数字
var index = Number(this.curNumber());
问题3
this.numbers
不是一个数组,它是一个observearray
。你不能直接索引到它
选项1
手动进入数组,然后通知值已更改(本质上)
选项2
拼接
splice
方法在observableArray
上实现,其行为与之完全相同,并且它将自动通知订阅者
您可以使用它以以下方式将新项目放置在特定索引上:
array.splice(index, 1, newItem);
这意味着:从位置索引
中取出一个项目,并将其放入新项目
因此,在你的情况下:
this.addNumber = function() {
var index = Number(this.curNumber());
var newValue = this.numbers()[index] + 1;
this.numbers.splice(index, 1, newValue);
}
在JSFIDLE上查看它:
我不熟悉knockout.js,但是
this.addNumber
函数中的索引应该是this.curNumber
而不是curNumber
?@jason kennaly,感谢您的快速响应。谢谢你的快速回复。我修好了第一根柱子。但我仍然有这个问题虽然这是有价值的输入,但它并没有真正回答问题Hi@Kenneth,我的答案与你的addNumber函数的函数实现相同,区别在于你调用的是valueHasMutated,但是ko.indexOf应该返回一个可观察的,我不确定你是否需要调用valueHasMutated,我认为应该通过敲除来“观察”增量不,它不是。indexOf只返回第一个匹配项的索引。无论你以后用那个值做什么,敲除都不会观察到。事实上,它的编写方式甚至不会增加值。它只会得到索引,然后递增并丢弃。这不是:this.numbers()[this.curNumber()]++;比您的答案可读性更强,parseInt很好,但也不是真正需要的,curNumber无论如何都不应该初始化为类似OP代码的字符串。此外,还需要调用valueHasMutated(),正如@Kenneth在其回答中指出的,无论您说什么。对于一个简单的问题,我真的没有时间阅读这么多的文本。检查一下我的小提琴。你不需要valueMutated。说话就像某人无缘无故地写那么长一行代码一样。是的,如果你想让KnockoutJS观察UI或其他观察对象中的变化,你需要这样做,这有点像KnockoutJS
array.splice(index, 1, newItem);
this.addNumber = function() {
var index = Number(this.curNumber());
var newValue = this.numbers()[index] + 1;
this.numbers.splice(index, 1, newValue);
}