在嵌套上下文中的更改事件处理程序中未获得正确的数据上下文

Not Getting Correct Data Context In Change Event Handler Within Nested Context

我在 with 绑定上下文中有一个 select

<div data-bind="with: SelectedItem">
    <select id="select" data-bind="options: $root.OptionsList, optionsText: 'description', optionsValue: 'opt_id', event: { change: $parent.OptionSelectionChanged }, optionsCaption: 'Select'"></select>
</div>

我原以为下面的输出包含 $root.OptionsList 中的选定项目,但我得到的是 $root.SelectedItem.

function MyViewModel() {
    self.OptionSelectionChanged = function(data, event) {
        console.log(data) // outputs $root.SelectedItem
    }
}

在此示例中,$root.OptionsList 是可应用于 $root.SelectedItem 的属性列表(它是 $root.AvailableItems 中某项的克隆,后者是更大的列表,关系,objects).

因此,当用户在更改事件中从包含 $root.OptionsList 的 Select 中选择一个选项时,我会更新 $root.SelectedItem.SelectedOptions,这会导致 UI 更新并重置Select 清空以再次显示标题。

如何在更改事件中获取所选选项的值?我做错了什么,还是我的期望 incorrect/misguided?我已经设法使用 jQuery 和 event.CurrentTarget 获得了值,但这似乎有点 "wrong" 即使它作为 Knockout 工作,我认为应该向我发送在下拉列表中选择的值。

我从来没有遇到过在 with 绑定中使用 select 绑定,而选项在某种程度上与 with 绑定中的对象相关的情况。在将元素发送到 change 处理程序时,with 绑定如何更改 binding context 似乎也很奇怪。

但是,解决方法是在 root 对象上定义一个 observable 来保存从 dropdown 中选择的值,并在select控制

<div data-bind="with: SelectedItem">
  <select id="select" data-bind="options: $root.OptionsList, optionsText: 'description', optionsValue: 'opt_id', optionsCaption: 'Select', value: $root.selectedOption"></select>
</div>

看看fiddle

  • event bidning is the current $data 绑定上下文的第一个参数。在你的情况下,它是 SelectedItem
  • 如果您想在下拉列表更改时调用函数,请使用 subscribe
  • 您需要将 value 绑定添加到 select

我仍然不确定为什么要在 with:SelectedItem 中添加 select。如果您 select 下拉列表中的默认 select 值,则下拉列表将根本不可见

这是一个在加载时设置了默认 SelectedItem 的工作片段

function MyViewModel() {
    const self = this;
    self.SelectedItem = ko.observable(1);
    self.OptionsList = ko.observableArray([{description: "1", opt_id:1},{description: "2", opt_id:2}])
    self.SelectedItem.subscribe(function(data) {
        console.log(data);
    })
}

ko.applyBindings(new MyViewModel())
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div data-bind="with: SelectedItem">
    <select id="select" data-bind="options: $root.OptionsList, optionsText: 'description', optionsValue: 'opt_id', value: $root.SelectedItem, optionsCaption: 'Select'"></select>
</div>