我有一个表格,其中包含从挖掘可观察数组中获取的项目,用户输入搜索文本并且巧合填充observableArray,此表格显示在模态上。每个项目都有一个按钮,用于打开另一个具有某些功能的模态(因为不相关而被忽略)。如果observableArray长度大于0,则表必须显示项目,否则,必须显示一行以指示没有结果显示。
<tr style="display: none" data-bind="visible: items().length == 0">
<td class="text-center alert alert-warning" colspan="4"><b>There's no coincidences</b></td>
</tr>
我的观点模型:
var viewModel = function () {
self.items= ko.observableArray([]);
//Modal is already on html, but not visible, to show it I use this
$('#searchProduct').modal('show');
//When modal is closed, the table is cleaned, so the items in observableArray are removed
$('#searchProduct').on('hidden.bs.modal', function () {
self.items.removeAll();
});
}
问题是第一次,可见绑定工作正常,但是当observableArray长度发生变化时(隐藏时调用removeAll),不会再次应用绑定。我知道是因为绑定已经应用,所以当observableArray更改时,长度会更新,但条件不能再次呈现html。
如何通过淘汰赛解决这个问题?
(我试图非常具体,但如果需要更多信息,我可以更新信息更清晰)
答案 0 :(得分:1)
您发布的代码应该可以正常运行。这是一个例子:
function Item() {
self.txt = ko.observable("Test observable");
}
function RootViewModel() {
var self = this;
self.items = ko.observableArray([new Item(), new Item()]);
$('#searchProduct').modal('show');
$('#searchProduct').on('hidden.bs.modal', function () {
self.items.removeAll();
});
}
ko.applyBindings(new RootViewModel());
pre { background: white; padding: 10px; color: #333; font: 11px consolas; border: 1px solid #ddd; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/js/bootstrap.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>
<div id="searchProduct" class="modal fade">
<div class="modal-dialog">
<div class="modal-content">Fake Modal</div>
</div>
</div>
<table>
<tbody>
<tr style="display: none" data-bind="visible: items().length == 0">
<td class="text-center alert alert-warning" colspan="4"><b>There's no coincidences</b>
</td>
</tr>
<!-- ko foreach: items -->
<tr>
<td data-bind="text: txt"></td>
</tr>
<!-- /ko -->
</tbody>
</table>
<hr>Debug info: <pre data-bind="text: ko.toJSON($root, null, 2)"></pre>
但请注意,我建议使用a custom binding handler for show/hide of a bs modal,您不应在视图模型中处理DOM交互(如on
处理程序)。
答案 1 :(得分:0)
调用removeAll会清空基础数组,并且您的两个observable似乎引用了相同的array.rather而不是调用removeAll,请执行self.items([]);
我创建了一个小提琴示例,用于添加到数组并从数组中删除所有内容。
http://jsfiddle.net/d7mpc6wa/4/
我看不到你的完整HTML代码,所以我在这里创建了一个类似的例子。
<强> HTML 强>
<table>
<tbody data-bind="foreach: items">
<tr><td data-bind="text:$data.name"></td></tr>
</tbody>
<tbody>
<tr data-bind="visible: items().length == 0">
<td class="text-center alert alert-warning" colspan="4"><b>There's no coincidences</b></td>
</tr>
</tbody>
</table>
<button data-bind="click:cleanArray">Clean Array</button>
<button data-bind="click:addArray">Add Array</button>
<强>视图模型强>
function VM() {
var self = this;
var arr = [{name:'name 1'},{name:'name 2'},{name:'name 3'}];
self.items = ko.observableArray(arr);
self.cleanArray = function(){
self.items([]);
}
self.addArray = function(){
self.items([]);
self.items(arr);
console.log(self.items());
};
}
ko.applyBindings(new VM());
如果有帮助,请告诉我
<强>更新强>
所以在这里我们可以将数组中的项目移除为self.items([]);
或self.items.removeAll();
,这样就会略有不同。
self.items([]);
将用新的空数组替换当前数组。但是self.items.removeAll()
将删除self.items
+中的所有项目,它将清空数组实例。
self.array = ['1', '2', '3'];
self.myArray1 = ko.observableArray(self.array);
self.myArray1.removeAll();
将清空self.myArray1
+它将清空self.array
以下示例清楚地解释了差异,请看一下。
谢谢
答案 2 :(得分:0)
我很惭愧,我发布的这些代码的一切都很好,错误是当我关闭模式时,我正在删除html中的所有警报类,这显然是在td元素中删除警告警告,所以相反或删除所有警报,什么不是purpouse,我从模态中删除警报危险。我真的很抱歉在SO上发布了这个愚蠢的问题,@ Jeroen,我知道将jQuery与knockout混合来隐藏模态是错误的,只是我不知道如何以正确的方式做到这一点。非常感谢你的回答。