所以我在我的申请中遇到了困难,我正试图完成。它应该发送一张清单,列出我想要的书的所有物。现在,我在淘汰赛中有几个视图模型,其中包含了通过json传入的数据。
我一直在尝试用正确的列表填充下拉列表,并跟踪发生的更改,但我没有任何运气。这是我一直试图使用的绑定,用于将列表附加到下拉列表。我可以填充它们,但是我不能选择任何东西。
function BookPossessionTransferVM() {
var self = this;
self.AllFromList = ([
{"IsAdult":false,"Name":"Bob","ID":38438},
{"IsAdult":false,"Name":"Gordon","ID":54686}
]);
self.PossessionChanges = ko.observableArray([]);
self.PossessionChanges.push(new PossessionChangeModel());
self.AvailableFrom = ko.computed(function() {
var possessionChangesValues = self.PossessionChanges(),
available = ko.utils.arrayFilter(self.AllFromList, function(selectedPerson) {
return !ko.utils.arrayFirst(possessionChangesValues , function (possessionChange) {
if (possessionChange.SelectedFrom() !== undefined) {
return possessionChange!= self &&
possessionChange.SelectedFrom().Name() === selectedPerson.Name;
} else {
return false;
}});
});
return available;
});
self.AvailableTo = ko.computed(function() {
var possessionChangesValues = self.PossessionChanges(),
available = ko.utils.arrayFilter(self.AllToList, function(selectedPerson) {
return !ko.utils.arrayFirst(possessionChangesValues , function (possessionChange) {
if (possessionChange.SelectedFrom() !== undefined) {
return possessionChange!= self &&
possessionChange.SelectedFrom().Name() === selectedPerson.Name;
} else {
return false;
}});
});
return available;
});
self.addPossessionChange = function () {
self.PossessionChanges.push(new PossessionChangeModel());
}
self.removePossessionChangeChange = function(possessionChange) {
self.PossessionChanges.remove(possessionChange);
}
}
function PossessionChangeModel() {
var self = this;
self.SelectedFrom = ko.observable(new SelectedPerson());
self.SelectedTo = ko.observable(new SelectedPerson());
self.ChangeType = ko.pureComputed(function() {
if (self.SelectedFrom() !== undefined && self.SelectedTo() !== undefined) {
return 'Update';
} else if (self.SelectedFrom() === undefined && self.SelectedTo() === undefined) {
return '';
} else if (self.SelectedFrom() === undefined) {
return 'Add';
} else if (self.SelectedTo() === undefined) {
return 'Remove';
} else { return ''; }
});
}
function SelectedPerson() {
var self = this;
self.IsAdult = ko.observable(false);
self.Name = ko.observable("None");
self.ID = ko.observable(0);
}
ko.bindingHandlers.select2 = {
init: function (element, valueAccessor, allBindingsAccessor, bindingContext) {
ko.utils.domNodeDisposal.addDisposeCallback(element,
function() {
$(element).select2('destroy');
});
var select2 = ko.utils.unwrapObservable(allBindingsAccessor().options);
$(element).select2(select2);
},
update: function (element, valueAccessor, allBindingsAccessor, bindingContext) {
var allBindings = allBindingsAccessor();
if ("value" in allBindings) {
if ((allBindings.select2.multiple || element.multiple) && allBindings.value().constructor != Array) {
$(element).val(allBindings.value().split(',')).trigger('change');
} else {
$(element).on('select2:selecting', function(e) {
var data = e.params.args.data.id;
console.log(data);
});
$(element).val(allBindings.value()).trigger('change');
}
}
$(element).trigger("change");
}
};
ko.applyBindings(new BookPossessionTransferVM()); #tblPossessionChanges {
width: 70%;
height: 100px;
text-align: center;
table-layout: fixed;
}
#tblReassignChanges td, #tblPossessionChanges th {
padding: 1rem;
}
#tblReassignChanges thead th {
text-align: center;
}
#tblReassignChanges thead th:first-child {
text-align: left;
width: 10%;
}
#tblReassignChanges tbody td:first-child {
text-align: left;
width: 10%;
}
#tblReassignChanges > tbody > tr > td.prompt > a{
font-weight: bold;
}
#tblReassignChanges tbody td select{
width: 75%
}<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.12/js/select2.full.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.12/css/select2.min.css" />
<div>
<table id="tblReassignChanges">
<thead>
<tr>
<th><a href="#" class="buttonSmall" data-bind="click: addPossessionChange">Add</a></th>
<th>From</th>
<th>To</th>
</tr>
</thead>
<tbody data-bind="foreach: PossessionChanges">
<tr>
<td class="prompt">
<a href="#" class="buttonSmall" data-bind="click: $root.removePossessionChange">Delete</a> </td>
<td>
<select class="form-control"
data-bind="options: $root.AvailableFrom,
value: SelectedFrom,
optionsText: 'Name',
optionsValue: 'ID',
select2: { placeholder: 'Please select a Person...', allowClear: true}"> </select>
</td>
<td>
<select class="form-control"
data-bind="options: $root.AvailableTo,
value: SelectedTo,
optionsText: 'Name',
optionsValue: 'ID',
select2: {placeholder: 'Please select a Person...', allowClear: true}"> </select>
</td>
<td>
<span id="changeTypeSpan" data-bind="text: ChangeType"></span>
</td>
</tr>
</tbody>
</table>
</div>
我还尝试将optionsValue更改为使用ID,但这会覆盖我所拥有的selectedPerson对象。我愿意接受所有的建议和帮助。谢谢!
编辑:这里是复制我的问题的jsFiddle,这样可以节省空间。我也用硬编码的数据。https://jsfiddle.net/3upb0mf8/5/
发布于 2020-01-30 11:59:22
你这里有很多问题:
possessionChange.SelectedFrom()包含整个person对象,而实际上它只包含它的id,因为这就是传递给optionsValue的内容。请read this answer完全理解它。您必须通过它的id.AvailableTo引用possessionChange.SelectedFrom()来检索此人,而不是possessionChange.SelectedTo().removePossessionChange与removePossessionChangeChange.PossesionChange必须有一个id,以便可以删除它。几乎没有其他问题。
我想我解决了大部分问题。还请注意,我使用的是PersonVM而不是普通对象:
function BookPossessionTransferVM() {
var self = this;
self.All = [new PersonVM(false,"Bob",38438), new PersonVM(false,"Gordon",54686)];
self.PossessionChanges = ko.observableArray([]);
self.AvailableFrom = ko.computed(function() {
var available = ko.utils.arrayFilter(self.All, function(item) {
return !ko.utils.arrayFirst(self.PossessionChanges() , function (possessionChange) {
var person = self.getPersonById(possessionChange.SelectedFrom());
if (person) {
return person.Name() === item.Name();
} else {
return false;
}
});
});
return available;
});
self.AvailableTo = ko.computed(function() {
var available = ko.utils.arrayFilter(self.All, function(item) {
return !ko.utils.arrayFirst(self.PossessionChanges() , function (possessionChange) {
var person = self.getPersonById(possessionChange.SelectedTo());
if (person) {
return person.Name() === item.Name();
} else {
return false;
}});
});
return available;
});
self.getPersonById = function (id) {
return ko.utils.arrayFirst(self.All, function(person){
return person.ID === id;
});
}
self.addPossessionChange = function () {
self.PossessionChanges.push(new PossessionChangeVM(self.PossessionChanges.length + 1));
}
self.removePossessionChange = function(possesion) {
self.PossessionChanges.remove(function (item) {
return possesion.possesionId() == item.possesionId();
});
}
}
function PossessionChangeVM(possesionId) {
var self = this;
self.possesionId = ko.observable(possesionId);
self.SelectedFrom = ko.observable();
self.SelectedTo = ko.observable();
self.ChangeType = ko.pureComputed(function() {
if (self.SelectedFrom() !== undefined && self.SelectedTo() !== undefined) {
return 'Update';
} else if (self.SelectedFrom() === undefined && self.SelectedTo() === undefined) {
return '';
} else if (self.SelectedFrom() === undefined) {
return 'Add';
} else if (self.SelectedTo() === undefined) {
return 'Remove';
} else { return ''; }
});
}
function PersonVM(isAdult, name, id) {
var self = this;
self.IsAdult = ko.observable(isAdult);
self.Name = ko.observable(name);
self.ID = ko.observable(id);
}
ko.bindingHandlers.select2 = {
init: function (element, valueAccessor, allBindingsAccessor, bindingContext) {
ko.utils.domNodeDisposal.addDisposeCallback(element,
function() {
$(element).select2('destroy');
});
var select2 = ko.utils.unwrapObservable(allBindingsAccessor().options);
$(element).select2(select2);
},
update: function (element, valueAccessor, allBindingsAccessor, bindingContext) {
var allBindings = allBindingsAccessor();
if ("value" in allBindings) {
if ((allBindings.select2.multiple || element.multiple) && allBindings.value().constructor != Array) {
$(element).val(allBindings.value().split(',')).trigger('change');
} else {
$(element).on('select2:selecting', function(e) {
var data = e.params.args.data.id;
});
$(element).val(allBindings.value()).trigger('change');
}
}
$(element).trigger("change");
}
};
ko.applyBindings(new BookPossessionTransferVM());#tblPossessionChanges {
width: 70%;
height: 100px;
text-align: center;
table-layout: fixed;
}
#tblReassignChanges td, #tblPossessionChanges th {
padding: 1rem;
}
#tblReassignChanges thead th {
text-align: center;
}
#tblReassignChanges thead th:first-child {
text-align: left;
width: 10%;
}
#tblReassignChanges tbody td:first-child {
text-align: left;
width: 10%;
}
#tblReassignChanges > tbody > tr > td.prompt > a{
font-weight: bold;
}
#tblReassignChanges tbody td select{
width: 75%
}<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.12/js/select2.full.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.12/css/select2.min.css" />
<div>
<table id="tblReassignChanges">
<thead>
<tr>
<th><a href="#" class="buttonSmall" data-bind="click: addPossessionChange">Add</a></th>
<th>From</th>
<th>To</th>
</tr>
</thead>
<tbody data-bind="foreach: PossessionChanges">
<tr>
<td class="prompt">
<a href="#" class="buttonSmall" data-bind="click: $root.removePossessionChange">Delete</a> </td>
<td>
<select class="form-control"
data-bind="options: $root.AvailableFrom,
value: SelectedFrom,
optionsText: 'Name',
optionsValue: 'ID',
select2: { placeholder: 'Please select a Person...', allowClear: true}"> </select>
</td>
<td>
<select class="form-control"
data-bind="options: $root.AvailableTo,
value: SelectedTo,
optionsText: 'Name',
optionsValue: 'ID',
select2: {placeholder: 'Please select a Person...', allowClear: true}"> </select>
</td>
<td>
<span id="changeTypeSpan" data-bind="text: ChangeType"></span>
</td>
</tr>
</tbody>
</table>
</div>
https://stackoverflow.com/questions/59977471
复制相似问题