asp.net mvc 核心 knockout.js 多个嵌套容器未正确绑定
asp.net mvc core knockout.js multiple nested containers not binding properly
这是我正在创建的测试应用程序的代码。
<style>
#scroll-wrapper {
margin: 5px;
max-height: 250px;
overflow: auto;
vertical-align: top;
}
#thumbnails {
vertical-align: top;
padding-bottom: 10px;
max-height: 500px;
min-width: 100px;
overflow-y: hidden;
overflow-x: scroll;
white-space: nowrap;
}
.thumbnail-container {
display: inline-block;
position: relative;
line-height: 5px;
margin: 3px;
margin-bottom: 15px !important;
}
#abc {
overflow-y: scroll;
overflow-x: hidden;
height: 200px;
}
<form method="post">
<div data-bind="foreach: lists" id="thumbnails">
<div class="thumbnail-container">
<span data-bind="text:listname"></span><br /><br /><br /><br /><br />
<div id="abc">
<ul class="list-group" data-bind="foreach: cardlists">
<li class="list-group-item">
<span data-bind="text: cardname"></span>
<a href="#" data-bind="click: $root.removecard">Del</a>
</li>
</ul>
<a href="#" data-bind="click: $parent.showhideaddcard">Add Card</a><br />
<div data-bind="visible: $parent.showRenderTimes">
<input type="text" data-bind="value: $parent.cardtext" /><br /><br /><br />
<input type="button" value="Add" data-bind="click: $parent.addcard" />
<input type="button" value="Cancel" data-bind="click: $parent.cancelcard" />
</div>
</div>
</div>
</div>
<p>
<span id="addVar" data-bind="click: addList">Add List</span>
</p>
<p class="alignRight">
<input type="submit" value="Check">
</p>
</form>
<script type="text/javascript">
var initialData = [
{
listname: "list1",containername :"container1", cardlists: [
{ cardname: "car1111111" },
{ cardname: "caddsdf" }]
},
{
listname: "list2",containername :"container2", cardlists: [
{ cardname: "card 1" },
{ cardname: "card 2" }]
},
{
listname: "list3", containername: "container3", cardlists: [
{ cardname: "card 1" },
{ cardname: "card 2" }]
},
{
listname: "list4", containername: "container4", cardlists: [
{ cardname: "card 1" },
{ cardname: "card 2" }]
},
{
listname: "list5", containername: "container5", cardlists: [
{ cardname: "card 1" },
{ cardname: "card 2" }]
},
{
listname: "list6", containername: "container6", cardlists: [
{ cardname: "card 1" },
{ cardname: "card 2" }]
},
{
listname: "list7", containername: "container7", cardlists: [
{ cardname: "card 3" },
{ cardname: "card 4" },
{ cardname: "card 5" },
{ cardname: "card 6" },
{ cardname: "card 7" },
{ cardname: "card 8" },
{ cardname: "card 9" },
{ cardname: "card 10" },
{ cardname: "card 11" }]
},
{
listname: "list6", containername: "container8", cardlists: [
{ cardname: "card 1" },
{ cardname: "card 2" }]
},
{
listname: "list6", containername: "container9", cardlists: [
{ cardname: "card 1" },
{ cardname: "card 2" }]
},
{
listname: "list6", containername: "container10", cardlists: [
{ cardname: "card 1" },
{ cardname: "card 2" }]
},
{
listname: "list6", containername: "container11", cardlists: [
{ cardname: "card 1" },
{ cardname: "card 2" }]
}
];
var ListModal = function(lists) {
var self = this;
self.showRenderTimes = ko.observable(false);
self.cardtext = ko.observable("ff");
self.lists = ko.observableArray(ko.utils.arrayMap(lists, function (list) {
return { listname: list.listname, containername:list.containername, cardlists: ko.observableArray(list.cardlists) };
}));
self.addList = function() {
self.lists.push({
listname: "abc",
containername:"container5",
cardlists: ko.observableArray([
{
cardname: "Bungle"
},
{
cardname: "George"
},
{
cardname: "Zippy"
}
])
});
};
self.addcard = function (lists) {
lists.cardlists.push({
cardname: self.cardtext
});
self.showRenderTimes(false);
};
self.cancelcard = function () {
self.showRenderTimes(false);
};
self.showhideaddcard = function (lists) {
self.showRenderTimes(true);
};
self.removecard = function (cardlist) {
$.each(self.lists(), function () { this.cardlists.remove(cardlist) })
};
self.save = function ()
{
};
};
ko.applyBindings(new ListModal(initialData));
</script>
代码生成此视图
现在应该发生什么,例如,当我单击图片中的第三张添加卡时,应该只会出现该文本框,但它会打开应用程序中的所有添加卡文本框。
显然绑定不正确。有人可以更正我的绑定,所以当我按 3 号容器添加卡时,只出现 3 号文本框。我认为 div abc 可能是问题所在,但我无法更正它。
绑定工作正常。问题是您只有一个父可观察对象来存储所有附加卡部分的可见状态。当然,如果每个部分都绑定到相同的 showRenderTimes
observable,那么它们将同时成为 hidden/visible。您需要为每个存储其可见性状态的列表创建一个可观察对象。
您可以将 showRenderTimes
从父级 ListModal
移动到单独的列表:
self.lists = ko.observableArray(ko.utils.arrayMap(lists, function (list) {
return { listname: list.listname, containername:list.containername, cardlists: ko.observableArray(list.cardlists), showRenderTimes: ko.observable(false) };
}));
然后您需要更新使用它的绑定以删除 $parent
上下文:
<!--<div data-bind="visible: $parent.showRenderTimes">-->
<div data-bind="visible: showRenderTimes">
并且您的 showHideAddCard
和 cancelCard
函数修改了被单击的列表中的变量,因此变为:
self.cancelcard = function (list) {
list.showRenderTimes(false);
};
self.showhideaddcard = function (list) {
list.showRenderTimes(true);
};
这是我正在创建的测试应用程序的代码。
<style>
#scroll-wrapper {
margin: 5px;
max-height: 250px;
overflow: auto;
vertical-align: top;
}
#thumbnails {
vertical-align: top;
padding-bottom: 10px;
max-height: 500px;
min-width: 100px;
overflow-y: hidden;
overflow-x: scroll;
white-space: nowrap;
}
.thumbnail-container {
display: inline-block;
position: relative;
line-height: 5px;
margin: 3px;
margin-bottom: 15px !important;
}
#abc {
overflow-y: scroll;
overflow-x: hidden;
height: 200px;
}
<form method="post">
<div data-bind="foreach: lists" id="thumbnails">
<div class="thumbnail-container">
<span data-bind="text:listname"></span><br /><br /><br /><br /><br />
<div id="abc">
<ul class="list-group" data-bind="foreach: cardlists">
<li class="list-group-item">
<span data-bind="text: cardname"></span>
<a href="#" data-bind="click: $root.removecard">Del</a>
</li>
</ul>
<a href="#" data-bind="click: $parent.showhideaddcard">Add Card</a><br />
<div data-bind="visible: $parent.showRenderTimes">
<input type="text" data-bind="value: $parent.cardtext" /><br /><br /><br />
<input type="button" value="Add" data-bind="click: $parent.addcard" />
<input type="button" value="Cancel" data-bind="click: $parent.cancelcard" />
</div>
</div>
</div>
</div>
<p>
<span id="addVar" data-bind="click: addList">Add List</span>
</p>
<p class="alignRight">
<input type="submit" value="Check">
</p>
</form>
<script type="text/javascript">
var initialData = [
{
listname: "list1",containername :"container1", cardlists: [
{ cardname: "car1111111" },
{ cardname: "caddsdf" }]
},
{
listname: "list2",containername :"container2", cardlists: [
{ cardname: "card 1" },
{ cardname: "card 2" }]
},
{
listname: "list3", containername: "container3", cardlists: [
{ cardname: "card 1" },
{ cardname: "card 2" }]
},
{
listname: "list4", containername: "container4", cardlists: [
{ cardname: "card 1" },
{ cardname: "card 2" }]
},
{
listname: "list5", containername: "container5", cardlists: [
{ cardname: "card 1" },
{ cardname: "card 2" }]
},
{
listname: "list6", containername: "container6", cardlists: [
{ cardname: "card 1" },
{ cardname: "card 2" }]
},
{
listname: "list7", containername: "container7", cardlists: [
{ cardname: "card 3" },
{ cardname: "card 4" },
{ cardname: "card 5" },
{ cardname: "card 6" },
{ cardname: "card 7" },
{ cardname: "card 8" },
{ cardname: "card 9" },
{ cardname: "card 10" },
{ cardname: "card 11" }]
},
{
listname: "list6", containername: "container8", cardlists: [
{ cardname: "card 1" },
{ cardname: "card 2" }]
},
{
listname: "list6", containername: "container9", cardlists: [
{ cardname: "card 1" },
{ cardname: "card 2" }]
},
{
listname: "list6", containername: "container10", cardlists: [
{ cardname: "card 1" },
{ cardname: "card 2" }]
},
{
listname: "list6", containername: "container11", cardlists: [
{ cardname: "card 1" },
{ cardname: "card 2" }]
}
];
var ListModal = function(lists) {
var self = this;
self.showRenderTimes = ko.observable(false);
self.cardtext = ko.observable("ff");
self.lists = ko.observableArray(ko.utils.arrayMap(lists, function (list) {
return { listname: list.listname, containername:list.containername, cardlists: ko.observableArray(list.cardlists) };
}));
self.addList = function() {
self.lists.push({
listname: "abc",
containername:"container5",
cardlists: ko.observableArray([
{
cardname: "Bungle"
},
{
cardname: "George"
},
{
cardname: "Zippy"
}
])
});
};
self.addcard = function (lists) {
lists.cardlists.push({
cardname: self.cardtext
});
self.showRenderTimes(false);
};
self.cancelcard = function () {
self.showRenderTimes(false);
};
self.showhideaddcard = function (lists) {
self.showRenderTimes(true);
};
self.removecard = function (cardlist) {
$.each(self.lists(), function () { this.cardlists.remove(cardlist) })
};
self.save = function ()
{
};
};
ko.applyBindings(new ListModal(initialData));
</script>
代码生成此视图
现在应该发生什么,例如,当我单击图片中的第三张添加卡时,应该只会出现该文本框,但它会打开应用程序中的所有添加卡文本框。
显然绑定不正确。有人可以更正我的绑定,所以当我按 3 号容器添加卡时,只出现 3 号文本框。我认为 div abc 可能是问题所在,但我无法更正它。
绑定工作正常。问题是您只有一个父可观察对象来存储所有附加卡部分的可见状态。当然,如果每个部分都绑定到相同的 showRenderTimes
observable,那么它们将同时成为 hidden/visible。您需要为每个存储其可见性状态的列表创建一个可观察对象。
您可以将 showRenderTimes
从父级 ListModal
移动到单独的列表:
self.lists = ko.observableArray(ko.utils.arrayMap(lists, function (list) {
return { listname: list.listname, containername:list.containername, cardlists: ko.observableArray(list.cardlists), showRenderTimes: ko.observable(false) };
}));
然后您需要更新使用它的绑定以删除 $parent
上下文:
<!--<div data-bind="visible: $parent.showRenderTimes">-->
<div data-bind="visible: showRenderTimes">
并且您的 showHideAddCard
和 cancelCard
函数修改了被单击的列表中的变量,因此变为:
self.cancelcard = function (list) {
list.showRenderTimes(false);
};
self.showhideaddcard = function (list) {
list.showRenderTimes(true);
};