![](/img/trans.png)
[英]Binding options and optionsText in Select dropdown in knockout.js
[英]binding multi dropdown list in knockout.js
我有多個下拉列表,需要執行以下操作:
1.確保在一個下拉列表中選擇值時,它不會出現在其他列表中(此處找不到合適的解決方案)。
2.選擇值“文本”時,將出現一個文本字段( <input>
),而不是“是/否”下拉列表。
3.“選擇選項”將僅出現在第一行(仍在起作用)。
4.確保如果選擇“文本”,它將始終位於頂部(仍在工作)。
HTML :
<div class='liveExample'>
<table width='100%'>
<tbody data-bind='foreach: lines'>
<tr>
<td>
Choose option:
</td>
<td>
<select data-bind='options: filters, optionsText: "name", value: filterValue'> </select>
</td>
<td data-bind="with: filterValue">
<select data-bind='options: filterValues, optionsText: "name", value: "name"'> </select>
</td>
<td>
<button href='#' data-bind='click: $parent.removeFilter'>Remove</button>
</td>
</tr>
</tbody>
</table>
<button data-bind='click: addFilter'>Add Choice</button>
JAVASCRIPT :
var CartLine = function() {
var self = this;
self.filter = ko.observable();
self.filterValue = ko.observable();
// Whenever the filter changes, reset the value selection
self.filter.subscribe(function() {
self.filterValue(undefined);
});
};
var Cart = function() {
// Stores an array of filters
var self = this;
self.lines = ko.observableArray([new CartLine()]); // Put one line in by default
// Operations
self.addFilter = function() { self.lines.push(new CartLine()) };
self.removeFilter = function(line) { self.lines.remove(line) };
};
ko.applyBindings(new Cart());
我會在這里感謝您的協助! 主要針對第一個問題。
謝謝!
麥克風
如果要基於UI中已選擇的選項來限制選項,則需要確保每個cartLine
都有自己的過濾器數組。 讓我們像這樣在構造函數中傳遞它:
var CartLine = function(availableFilters) {
var self = this;
self.availableFilters = availableFilters;
// Other code
// ...
};
您必須使用此新的viewmodel屬性,而不是全局filters
數組:
<td>
<select data-bind='options: availableFilters,
optionsText: "name",
value: filterValue'> </select>
</td>
現在,我們必須找出在創建新的cartLine
實例時哪些過濾器仍然可用。 Cart
管理所有lines
,並具有addFilter
功能。
self.addFilter = function() {
var availableFilters = filters.filter(function(filter) {
return !self.lines().some(function(cartLine) {
var currentFilterValue = cartLine.filterValue();
return currentFilterValue &&
currentFilterValue.name === filter.name;
});
});
self.lines.push(new CartLine(availableFilters))
};
新的CartLine
實例僅獲取尚未在其他任何行中使用的過濾器。 (注意:如果要在較舊的瀏覽器中使用Array.prototype.some
,則可能需要使用polyfill )
剩下的唯一的事情就是用戶體驗決定,而不是“編碼決定”:您是否希望用戶在添加新決定后能夠更改以前的“選擇”? 如果是這種情況,則需要創建計算的availableFilters
數組,而不是普通的數組。
這是一個包含我上面發布的代碼的分叉小提琴: http : //jsfiddle.net/ztwcqL69/請注意,您可以創建雙選,因為在添加新選項之后,選項仍可編輯。 如果您評論期望的行為,我可以幫助您找到解決方法。 這可能需要進行一些大的更改...我提供的解決方案更多是朝着正確方向的指針。
編輯:我為沒有提供最終解決方案感到難過,所以這是另一種方法:
如果要追溯更新availableFilters
,可以這樣進行:
CartLine
引用其siblings
(其他購物ko.computed
, 並通過使用siblings
及其filterValue
的ko.computed
創建對任何更改的filterValue
:
var CartLine = function(siblings) {
var self = this;
self.availableFilters = ko.computed(function() {
return filters.filter(function(filter) {
return !siblings()
.filter(function(cartLine) { return cartLine !== self })
.some(function(cartLine) {
var currentFilterValue = cartLine.filterValue();
return currentFilterValue &&
currentFilterValue.name === filter.name;
});
});
});
// Other code...
};
像這樣創建新的購物self.lines.push(new CartLine(self.lines))
: self.lines.push(new CartLine(self.lines))
。 從一個空數組開始,然后使用addFilter
推入第一個CartLine
。
關於點2:您可以創建一個基於filterValue排序的可計算觀察值:
self.sortedLines = ko.computed(function() {
return self.lines().sort(function(lineA, lineB) {
if (lineA.filterValue() && lineA.filterValue().name === "Text") return -1;
if (lineB.filterValue() && lineB.filterValue().name === "Text") return 1;
return 0;
});
});
第3點 :將其移至foreach
之外。
第4點 :使用if
綁定:
<td data-bind="with: filterValue">
<!-- ko if: name === "Text" -->
<input type="text">
<!-- /ko -->
<!-- ko ifnot: name === "Text" -->
<select data-bind='options: filterValues, optionsText: "name", value: "name"'> </select>
<!-- /ko -->
<td>
更新的小提琴包含以下代碼: http : //jsfiddle.net/z22m1798/
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.