我正在尝试创建一个表格,其中新项目将以不同的背景颜色显示。下面的示例显示了我正在做的事情。
var data = [{
name: "Gibson",
id: "1"
}, {
name: "Fender",
id: "2"
}, {
name: "Godin",
id: "3"
}, {
name: "Tagima",
id: "4"
}, {
name: "Giannini",
id: "5"
}];
var list = [{
name: "Gibson",
id: "1"
}, {
name: "Fender",
id: "2"
}];
var ViewModel = function() {
var self = this;
self.mylist = ko.mapping.fromJS(list);
self.data = ko.mapping.fromJS(data);
self.selectedItem = ko.observable(undefined);
self.addItem = function() {
if (self.selectedItem == undefined) return;
self.mylist.push(self.selectedItem());
$("#" + self.selectedItem().id()).addClass("newItem");
self.selectedItem(undefined);
}
}
var viewModel = new ViewModel();
ko.applyBindings(viewModel);
.newItem {
background-color: #DCEDC1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<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.mapping/2.4.1/knockout.mapping.min.js"></script>
<select data-bind="options: $root.data, optionsText: 'name', optionsCaption: 'Select yout Guitar', value: selectedItem, event:{change: $root.addItem}"></select>
<table>
<thead>
<tr>
<th>
<p>
Guitars
</p>
</th>
</tr>
</thead>
<tbody data-bind="foreach:mylist">
<tr data-bind="attr:{id: $data.id}">
<td>
<p data-bind="text: $data.name"></p>
</td>
</tr>
</tbody>
</table>
但在某些 View 中,表中的新行是在函数 addItem 完成后添加的,因此背景颜色不会改变。有其他方法可以做到这一点或解决此问题吗?
最佳答案
如果您还使用 knockout ,那么使用 jQuery 来跟踪类将会很困难。如果您的吉他对象保持简单,您可以用很少的代码实现您的功能(如果您不想,则不必创建新的 View 模型)。这是您需要做的:
- 跟踪数组中的所有新项目
- 对于每个项目,确定他们是否需要
.isNew
通过检查它们是否在此数组中来定义类 - 使用
css
切换类绑定(bind)
第 1 步:
内部ViewModel
您可以创建第三个 observableArray
。 myList
仍然存储所有选定的项目,新数组 newItems
仅存储 id
通过 UI 添加的项目的属性。
第 2 步:
在 addItem
方法,我们不是通过 jQuery 选择元素并添加类,而是将新项目推送到 newItems
数组。
第 3 步:
替换 attr
与 css
绑定(bind)绑定(bind)创建一个计算 bool 值来指示该行是否是新的:
<tr data-bind="css:{'newItem' : guitarIsInArray($data, $parent.newItems())}">
附加说明:
- 您正在使用
selectedValue
存储<select>
元素的更改:最好订阅该值的更改,而不是通过event: { change: fn }
创建另一个事件监听器 - 由于您的吉他只是普通物体,
data
中的Gibson数组将不等于myList
中的 Gibson 。我创建了一个辅助方法来确保您不会获得重复的值 (guitarIsInArray
)。 - 最终,即使您没有创建
Guitar
viewmodel,我会尝试确保代码中每把吉他只有一个对象引用。
这是一个更新的示例:
var data = [{
name: "Gibson",
id: "1"
}, {
name: "Fender",
id: "2"
}, {
name: "Godin",
id: "3"
}, {
name: "Tagima",
id: "4"
}, {
name: "Giannini",
id: "5"
}];
var list = [{
name: "Gibson",
id: "1"
}, {
name: "Fender",
id: "2"
}];
var ViewModel = function() {
var self = this;
self.data = ko.mapping.fromJS(data);
self.mylist = ko.mapping.fromJS(list);
self.newItems = ko.observableArray([]);
// This excludes any guitar in mylist from data
self.unusedData = ko.computed(function() {
return self.data().filter(function(guitar) {
return !guitarIsInArray(guitar, self.mylist());
});
});
self.selectedItem = ko.observable();
// Called whenever your select changes
self.selectedItem.subscribe(function(newItem) {
if (!newItem || guitarIsInArray(newItem, self.mylist())) {
return;
}
self.mylist.push(newItem);
self.newItems.push(newItem);
});
}
var viewModel = new ViewModel();
ko.applyBindings(viewModel);
function guitarIsInArray(guitar, array) {
for (var g = 0; g < array.length; g += 1) {
if (array[g].id() === guitar.id()) {
return true;
}
}
return false;
};
.newItem {
background-color: #DCEDC1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<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.mapping/2.4.1/knockout.mapping.min.js"></script>
<select data-bind="options: $root.unusedData, optionsText: 'name', optionsCaption: 'Select your Guitar', value: selectedItem"></select>
<table>
<thead>
<tr>
<th>
<p>
Guitars
</p>
</th>
</tr>
</thead>
<tbody data-bind="foreach:mylist">
<tr data-bind="css:{'newItem' : guitarIsInArray($data, $parent.newItems())}">
<td>
<p data-bind="text: $data.name"></p>
</td>
</tr>
</tbody>
</table>
关于javascript - 使用 Knockout 将项目添加到列表后更改背景颜色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37596770/