有没有办法将数组元素绑定为输入值或选择?
像这样......
var ViewModel = function() {
var self = this;
self.array = ko.observableArray([undefined, undefined, undefined]);
self.text = ko.computed(function() {
return self.array()[0] + self.array()[1] + self.array()[2];
});
}
var viewModel = new ViewModel();
ko.applyBindings(viewModel);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<input data-bind="value: $root.array[0]" />
<input data-bind="value: $root.array[1]" />
<input data-bind="value: $root.array[2]" />
<p data-bind="text: $root.text"></p>
修改
对不起伙计们,我提出问题真的很糟糕,但是我的问题有点棘手,我的真实条目是选择,它是数组的过滤器和选择的值。像这样:
var ViewModel = function() {
var self = this;
self.family = ko.mapping.fromJS(data.family);
self.array = ko.observableArray([ko.observable(undefined), ko.observable(undefined), ko.observable(undefined)]);
self.filterFamily1 = function() {
return self.family().filter(function(i) {
return i.parent() == null;
});
}
self.filterFamily2 = ko.computed(function() {
return ko.utils.arrayFilter(self.family, function(i) {
return i.parent() === self.array()[0]().name();
});
});
self.filterFamily3 = ko.computed(function() {
return ko.utils.arrayFilter(self.family, function(i) {
return i.parent() === self.array()[1]().name();
});
})
}
var data = {
family: [{
name: "John",
parent: null
}, {
name: "Mary",
parent: null
}, {
name: "Erick",
parent: "John"
}, {
name: "Paul",
parent: "John"
}, {
name: "Marshall",
parent: "Mary"
}, {
name: "Ross",
parent: "Paul"
}]
};
var viewModel = new ViewModel();
ko.applyBindings(viewModel);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.min.js"></script>
<select data-bind="options: $root.filterFamily1(),optionsText: 'name', value: $root.array()[0]"></select>
<select data-bind="options: $root.filterFamily2(),optionsText: 'name', value: $root.array()[1]"></select>
<select data-bind="options: $root.filterFamily3(),optionsText: 'name', value: $root.array()[2]"></select>
但答案适合我之前描述的问题。
答案 0 :(得分:4)
由于您的问题发生了很大变化,我发布了一个新答案:
您的代码段有控制台错误:您最初选择的值未设置,也未检查未定义。包括这些检查,一切正常。
请注意,您绝对可以提高可读性并重构重复的代码段。
aggregateByKey
var ViewModel = function() {
var self = this;
self.family = ko.mapping.fromJS(data.family);
self.filterFamily1 = ko.computed(function() {
return self.family().filter(function(i) {
return i.parent() === null;
});
});
self.array = ko.observableArray([
ko.observable(self.filterFamily1()[0]),
ko.observable(undefined),
ko.observable(undefined)
]);
self.filterFamily2 = ko.computed(function() {
return self.family().filter(function(i) {
return self.array()[0]() && i.parent() === self.array()[0]().name();
});
});
self.filterFamily3 = ko.computed(function() {
return self.family().filter(function(i) {
return self.array()[1]() && i.parent() === self.array()[1]().name();
});
})
}
var data = {
family: [{
name: "John",
parent: null
}, {
name: "Mary",
parent: null
}, {
name: "Erick",
parent: "John"
}, {
name: "Paul",
parent: "John"
}, {
name: "Marshall",
parent: "Mary"
}, {
name: "Ross",
parent: "Paul"
}]
};
var viewModel = new ViewModel();
ko.applyBindings(viewModel);
答案 1 :(得分:3)
Yessir,当然有。但是:
observable
s。self.array
函数。以下是一个例子:
var ViewModel = function() {
var self = this;
self.array = ko.observableArray([ko.observable(""), ko.observable(""), ko.observable("")]);
self.text = ko.computed(function() {
return self.array()[0]() + self.array()[1]() + self.array()[2]();
});
}
var viewModel = new ViewModel();
ko.applyBindings(viewModel);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<input data-bind="value: $root.array()[0]" />
<input data-bind="value: $root.array()[1]" />
<input data-bind="value: $root.array()[2]" />
<p data-bind="text: $root.text"></p>
但是,为什么不使用foreach
绑定和其他一些不错的改进?
var ViewModel = function() {
var self = this;
self.array = ko.observableArray([
{ txt: ko.observable("a") },
{ txt: ko.observable("b") },
{ txt: ko.observable("c") },
{ txt: ko.observable("d") }
]);
self.text = ko.computed(function() {
return self.array().map(function(obs) { return obs.txt(); }).join("");
});
}
var viewModel = new ViewModel();
ko.applyBindings(viewModel);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>
<!-- ko foreach: array -->
<input data-bind="textInput: txt">
<!-- /ko -->
<p data-bind="text: text"></p>
答案 2 :(得分:2)
如果要按索引访问数组,则需要先使用()
评估observable。
如果您希望value
绑定以双向方式工作(即:不仅最初设置它,还要在更改后更新viewmodel中的值),您必须将它们绑定到{{ 1}}变量。
其他改进:
如果您想将所有值加在一起,可以使用ko.observable
或reduce
和map
的组合来附加字符串。
编辑:我错了!
如果需要输入所有数组的值,也可以使用join
绑定并使用foreach
来引用当前值。
实际上,您无法使用$data
关键字创建双向绑定。如果您使用$data
observable。
参考:https://github.com/knockout/knockout/issues/708
$index
var ViewModel = function() {
var self = this;
self.array = ko.observableArray([ko.observable("a"), ko.observable("b"), ko.observable("c")]);
self.text = ko.computed(function() {
return self.array()[0]() + self.array()[1]() + self.array()[2]();
});
self.reducedText = ko.computed(function() {
return self.array()
.reduce(function(prev, curr) {
return prev + curr();
}, "");
});
};
var viewModel = new ViewModel();
ko.applyBindings(viewModel);