我的目标是拥有一个动态增长的输入字段列表 - 每当我开始在输入字段中输入时,它下面都会出现一个新的空字符。
我期待这样的事情发挥作用;
function Model() {
// Build a basic observable array
this.inputs = ko.observableArray();
// Whenever this changes, or on initial creation of this computed
// add a new empty field if the last one has any text in it.
ko.computed(function () {
var len = this.inputs().length;
// If there are no fields (initial run) or the last element is falsey...
if (!len || this.inputs()[len-1]()) {
// Create a new observable and add it to the array.
this.inputs.push(ko.observable(""));
}
}, this);
}
下面是一些将模型绑定到的基本HTML;
<ul data-bind="foreach: inputs">
<li><input data-bind="textInput: $data" /></li>
</ul>
当我输入正确显示的文本框(显示此函数在创建时运行)时,不会调用计算。
那么我必须做些什么来让计算机正确地重新评估?有没有更好的方法来实现一个实际上在淘汰赛中有效的动态增长列表?
这里是jsfiddle我在这里的确切代码,以帮助调试此问题。
答案 0 :(得分:1)
当前实现无法按预期运行有两个原因:
$data
context属性,根据docs,该属性是提供给observable的字符串。绑定到$rawData
属性以绑定到实际的observable。!len
检查。
function Model() {
this.inputs = ko.observableArray([ko.observable("")]);
ko.computed(function() {
if (!!this.inputs()[this.inputs().length - 1]()) {
this.inputs.push(ko.observable(""));
}
}, this);
}
ko.applyBindings(new Model());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<ul data-bind="foreach: inputs">
<li>
<input data-bind="textInput: $rawData" />
</li>
</ul>
以下是另一种例行程序。它递归地添加了一个observable。添加observable时,会创建订阅以跟踪其更改。当它变为非空值时,处理订阅(只需要一次)并重复例程。
function Model() {
this.inputs = ko.observableArray();
this.addItem = function() {
var newItem = ko.observable("");
this.inputs.push(newItem);
var sub = newItem.subscribe(function(newValue) {
if (!!newValue) {
sub.dispose();
this.addItem();
}
}, this);
}
this.addItem();
}
ko.applyBindings(new Model());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<ul data-bind="foreach: inputs">
<li>
<input data-bind="textInput: $rawData" />
</li>
</ul>