使用敲除绑定更改选择事件,我怎么知道它是否真正改变

guy*_*ler 82 knockout.js

我正在构建权限UI,我有一个权限列表,每个权限旁边都有一个选择列表.权限由可观察的对象数组表示,这些对象绑定到选择列表:

<div data-bind="foreach: permissions">
     <div class="permission_row">
          <span data-bind="text: name"></span>
          <select data-bind="value: level, event:{ change: $parent.permissionChanged}">
                   <option value="0"></option>
                   <option value="1">R</option>
                   <option value="2">RW</option>
           </select>
      </div>
 </div>
Run Code Online (Sandbox Code Playgroud)

现在的问题是:当UI刚刚第一次填充时,会引发更改事件.我调用我的ajax函数,获取权限列表,然后为每个权限项引发事件.这真的不是我想要的行为.我希望只有当用户真正为选择列表中的权限选择一个新值时才会引发它,我该怎么做?

Sar*_*ath 97

实际上,您想要查找事件是由用户还是程序触发,并且显然该事件将在初始化时触发.

添加的淘汰方法subscription在所有情况下都无济于事,为什么因为在大多数模型中都会像这样实现

  1. 用未定义的数据初始化模型,只是结构 (actual KO initilization)
  2. 使用初始数据更新模型 (logical init like load JSON , get data etc)
  3. 用户交互和更新

我们要捕获的实际步骤是3中的更改,但是第二步subscription将调用,所以更好的方法是添加到事件更改之类的

 <select data-bind="value: level, event:{ change: $parent.permissionChanged}">
Run Code Online (Sandbox Code Playgroud)

并在permissionChanged功能中检测到事件

this.permissionChanged = function (obj, event) {

  if (event.originalEvent) { //user changed

  } else { // program changed

  }

}
Run Code Online (Sandbox Code Playgroud)

  • 我认为这应该被标记为正确的答案.我有问题中描述的确切场景,我测试了传递字符串作为`select`元素的键.但是,即使select的初始值与其中一个选项匹配,它仍会触发`change`事件.当我在处理程序中实现这个简单的`if`块时,一切都按预期工作.首先尝试这种方法.谢谢,@萨拉斯! (4认同)

Mic*_*est 32

这只是猜测,但我认为它正在发生,因为它level是一个数字.在这种情况下,value绑定将触发change事件以level使用字符串值进行更新.因此,您可以通过确保level是一个字符串来解决此问题.

此外,更多"Knockout"这样做的方法是不使用事件处理程序,而是使用observable和subscriptions.创建level一个可观察的,然后添加一个订阅,它将在每次level更改时运行.