我有两个<select>
菜单和文本框。当选择第一个菜单中的选项时,它应该更新文本框中的值,并且还应该在第二个选择菜单中设置所选选项。
文本框正确更新。
但是,第二个选择菜单未更新。
ParentID
第一个菜单中的值应用于指定 TaskID
第二个菜单的值。 ParentID
值是对 TaskID
的 FK 引用在同一张表中。
例如,在下面,如果在第一个菜单中选择“ManualItems”,则“Positions”应成为在第二个菜单中选择的值。
var viewModel = function(data) {
var self = this;
// variables
self.currentTask = ko.observable();
self.selectedParentTask = ko.observable();
self.taskDescription = ko.observable("");
self.tasks = ko.observableArray([
{TaskID: 1, TaskName: "ManualItems", TaskDescription: "Manual Rec", ParentID: 4, ParentName: "Positions"},
{TaskID: 2, TaskName: "Trades", TaskDescription: "Trades Data", ParentID: null, ParentName: null},
{TaskID: 3, TaskName: "File-In", TaskDescription: "File Detail", ParentID: 2, ParentName: "Trades"},
{TaskID: 4, TaskName: "Positions", TaskDescription: "Positions Overview", ParentID: null, ParentName: null}
]);
self.parentTasks = ko.observableArray([
{TaskID: 1, TaskName: "ManualItems", TaskDescription: "Manual Rec", ParentID: 4, ParentName: "Positions"},
{TaskID: 2, TaskName: "Trades", TaskDescription: "Trades Data", ParentID: null, ParentName: null},
{TaskID: 3, TaskName: "File-In", TaskDescription: "File Detail", ParentID: 2, ParentName: "Trades"},
{TaskID: 4, TaskName: "Positions", TaskDescription: "Positions Overview", ParentID: null, ParentName: null}
]);
/*
self.currentTask.subscribe(function(newValue){
self.selectedParentTask(newValue);
});
*/
self.EditTask = function () {
// populate all fields with selected task
self.taskDescription(self.currentTask().TaskDescription);
self.selectedParentTask(self.currentTask()); // set parent task to the ParentID value of currentTask
};
};
ko.applyBindings(new viewModel());
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div class="form-group">
<label for="taskName">Edit Existing Task</label>
<select class="form-control" id="taskNameSelect" data-bind="
options: tasks,
optionsText: 'TaskName',
value: currentTask,
event: {change: $root.EditTask},
optionsCaption: 'Select Task...'
"></select>
</div>
<div class="form-group">
<label for="taskParent">Select Parent Task</label>
<select class="form-control" id="taskParent" data-bind="
options: parentTasks,
optionsText: 'TaskName',
value: selectedParentTask,
optionsCaption: 'Select Parent Task...'
"></select>
</div>
<div class="form-group">
<label for="taskDescription">Task Description</label>
<textarea class="form-control" id="taskDescription" rows="3" placeholder="Enter Task Description" data-bind="value: taskDescription"></textarea>
</div>
这是 JSFiddle 中的代码也是如此。
最佳答案
作为一般规则,避免在 knockout 中设置 DOM 事件处理程序。大多数时候,通过使用订阅,您可以用更少的代码和更少的歧义来完成同样的任务。
在这种情况下,您希望通过查找与其匹配的父任务来对 currentTask
中的更改使用react。
ko.utils.arrayFirst()
是一个方便的 utility function从数组中取出符合特定条件的第一个元素。 (现在您也可以使用 Array#find
达到相同的效果。)
所以,我们得到:
self.currentTask.subscribe(function (task) {
var matchingParentTask = ko.utils.arrayFirst(self.parentTasks(), function (parent) {
return parent.TaskName === task.ParentName;
});
self.parentTask(matchingParentTask);
self.taskDescription(task.TaskDescription);
});
在上下文中:
var viewModel = function(data) {
var self = this;
// variables
self.currentTask = ko.observable();
self.parentTask = ko.observable();
self.taskDescription = ko.observable();
self.tasks = ko.observableArray([
{TaskID: 1, TaskName: "ManualItems", TaskDescription: "Manual Rec", ParentID: 4, ParentName: "Positions"},
{TaskID: 2, TaskName: "Trades", TaskDescription: "Trades Data", ParentID: null, ParentName: null},
{TaskID: 3, TaskName: "File-In", TaskDescription: "File Detail", ParentID: 2, ParentName: "Trades"},
{TaskID: 4, TaskName: "Positions", TaskDescription: "Positions Overview", ParentID: null, ParentName: null}
]);
self.parentTasks = ko.observableArray([
{TaskID: 1, TaskName: "ManualItems", TaskDescription: "Manual Rec", ParentID: 4, ParentName: "Positions"},
{TaskID: 2, TaskName: "Trades", TaskDescription: "Trades Data", ParentID: null, ParentName: null},
{TaskID: 3, TaskName: "File-In", TaskDescription: "File Detail", ParentID: 2, ParentName: "Trades"},
{TaskID: 4, TaskName: "Positions", TaskDescription: "Positions Overview", ParentID: null, ParentName: null}
]);
self.currentTask.subscribe(function (task) {
var matchingParentTask = ko.utils.arrayFirst(self.parentTasks(), function (parent) {
return parent.TaskName === task.ParentName;
});
self.parentTask(matchingParentTask);
self.taskDescription(task.TaskDescription);
});
};
ko.applyBindings(new viewModel());
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div class="form-group">
<label for="taskName">Edit Existing Task</label>
<select class="form-control" id="taskNameSelect" data-bind="
value: currentTask,
options: tasks,
optionsText: 'TaskName',
optionsCaption: 'Select Task...'
"></select>
</div>
<div class="form-group">
<label for="taskParent">Select Parent Task</label>
<select class="form-control" id="taskParent" data-bind="
value: parentTask,
options: parentTasks,
optionsText: 'TaskName',
optionsCaption: 'Select Parent Task...'
"></select>
</div>
<div class="form-group">
<label for="taskDescription">Task Description</label>
<textarea class="form-control" id="taskDescription" rows="3" placeholder="Enter Task Description" data-bind="value: taskDescription"></textarea>
</div>
关于javascript - KnockoutJS - 根据另一个菜单中的选择设置选择菜单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44280687/