javascript - 两种方式的数据绑定不适用于淘汰 ObservableArrays
问题描述
我有以下代码,它有两个功能。
- 单击“添加更多”时,将新值推送到可观察数组,将新文本框添加到 UI
- 单击保存时,会在 div 的文本框中显示值。
var model = function() {
var self = this;
self.inventoryItems = ko.observableArray();
myArray = ["Value1", "V1lue2", "Value3", "Value4"];
self.inventoryItems(myArray);
self.addItems = function(vm) {
self.inventoryItems.push('New Item');
}
self.SaveInventory = function(data) {
$('#htmlBlock').html(myArray);
console.log(myArray)
};
};
ko.applyBindings(new model());
ul {
list-style: none;
}
li {
margin-top: 5px;
}
.info-text,
a,
button {
margin-top: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<ul data-bind="foreach: inventoryItems">
<li>
<input data-bind="value: $data" />
</li>
</ul>
<div>
<a data-bind="click: addItems">+ Add more</a>
</div>
<button type="submit" class="btn btn-accent" data-bind="click: SaveInventory">Save changes</button>
<div class='info-text' id="htmlBlock">
</div>
使用此代码,我的 UI 可以正常初始化,当我单击 'Add more' 时,能够获得一个新的文本框,并且 myArray/inventoryItems 也可以正常工作。
但是,如果我编辑任何项目并保存该值,我将无法取回更新值。
我错过了什么?
解决方案
不需要单独引用可观察数组中的底层数组,它只会混淆事物。使用 读出值self.inventoryItems()
。
实时查看模型外观的一个好方法是使用带有data-bind="text: ko.toJSON($data, null, '\t')"
为了进行双向绑定,您需要使每个值(对于输入字段)可观察。通常我会为此使用单独的构造函数。
function EditableField(initialValue) {
// each value you want to be able to have a two-way binding for needs to be observable
this.value = ko.observable(initialValue);
}
var model = function() {
var self = this;
self.inventoryItems = ko.observableArray(["Value1", "V1lue2", "Value3", "Value4"].map(function(item) {
// run each array value through constructor
return new EditableField(item);
}));
self.addItems = function(vm) {
self.inventoryItems.push(new EditableField('New Item'));
}
self.SaveInventory = function(data) {
console.log(ko.toJS(self.inventoryItems)); // fetch the updated array
};
};
ko.applyBindings(new model());
ul {
list-style: none;
}
li {
margin-top: 5px;
}
.info-text,
a,
button {
margin-top: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<ul data-bind="foreach: inventoryItems">
<li>
<!-- use textInput binding for live updates, bound to the value property from constructor -->
<input data-bind="textInput: value" />
</li>
</ul>
<div>
<a data-bind="click: addItems">+ Add more</a>
</div>
<button type="submit" class="btn btn-accent" data-bind="click: SaveInventory">Save changes</button>
<!-- display the model in real time -->
<pre class='info-text' data-bind="text: ko.toJSON($data, null, '\t')">
</pre>
推荐阅读
- rust - 编译器是否有某种顺序运行?
- php - 页面 404 未找到,但直到几次前才工作
- r - testhat - 如何存储预期结果?
- python - 我想从不同的python3脚本在python脚本中添加一个变量,该变量将充当全局变量或该变量的一个访问点
- xml - 另一个CDATA中的xml请求CDATA如何转义
- node.js - 如何从 lambda 过早返回
- spring-boot - 如何在 Spring Kafka 2.2.9.RELEASE 中将 Retry Tempate (backOffPolicy) 与 AfterRollbackProcessor 一起使用
- ionic4 - 如何使用 duallKnobs 检测 ionic 4 ion-range 中哪个旋钮发生了变化?
- python - 如何在一行中从多个模块导入变量?
- c# - c#从当前表单按钮单击打开另一个表单