簡體   English   中英

使用knockout將數組元素數據綁定為值

[英]Data-bind an array element as value using knockout

有沒有辦法將數組元素綁定為輸入值或選擇值?

像這樣......

 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> 

但答案適合我之前描述的問題。

由於您的問題發生了很大變化,我發布了一個新答案:

您的代碼段有控制台錯誤:您最初選擇的值未設置,也未檢查未定義。 包括這些檢查,一切正常。

請注意,您絕對可以提高可讀性並重構重復的代碼部分。

 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); 
 <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> 

Yessir肯定有。 但:

  1. 物品本身必須是observable的。
  2. 您應該在綁定到其中一個元素之前執行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> 

如果要按索引訪問數組,則需要首先使用()來評估observable。

如果您希望value綁定以雙向方式工作(即:不僅最初設置它,而且還在更改后更新viewmodel中的值),則必須將它們綁定到ko.observable變量。

其他改進:

如果要將所有值連接在一起,可以使用reducemapjoin的組合來追加字符串。

編輯:我錯了! 如果需要輸入所有數組的值,也可以使用foreach綁定並使用$data來引用當前值。

實際上,您無法使用$data關鍵字創建雙向綁定。 如果使用$index observable,則可以。

參考: https//github.com/knockout/knockout/issues/708

 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); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> <input data-bind="value: array()[0]" /> <input data-bind="value: array()[1]" /> <input data-bind="value: array()[2]" /> <p data-bind="text: text"></p> <!-- EDIT: this does not create a two way binding <div data-bind="foreach: array"> <input data-bind="value: $data" /> </div> --> <!-- EDIT: this does work --> <div data-bind="foreach: array"> <input data-bind="value: $parent.array()[$index()]" /> </div> <p data-bind="text: reducedText"></p> 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM