knockout.js - 手动订阅中的 beforeChange 具有奇怪的行为

标签 knockout.js coffeescript ko.observablearray

在我的 View 模型中有一个文件、文件类型和未使用的文件类型的列表:

viewModel =
  files: ko.observableArray([
        new File({name: "A1", id: 1})
        new File({name: "B1", id: 2})
        new File({name: "C1", id: 3})
        new File({name: "D1", id: 4})
    ])
  types:  ko.observableArray(dataTypes)
  typesUnused: ko.observableArray(dataTypes)

我创建了一个 File 类,并在其中创建了一个 type 属性。 要填充未使用的文件类型列表,请订阅 type 属性的 beforeChange 和其他 afterChange 属性

class File
  constructor: (data) ->
    @name = data.name
    @id = data.id
    @type = ko.observable(null)

    # Updates array of types not used
    @type.subscribe ((oldValue) ->
      console.log "OLD: #{oldValue}"
      viewModel.typesUnused.remove (item) -> item is oldValue if oldValue
    ), @, "beforeChange"
    @type.subscribe (newValue) ->        
      console.log "NEW: #{newValue}"
      if newValue && viewModel.typesUnused.indexOf(newValue) < 0 
        viewModel.typesUnused.push newValue

想法
这个想法是,每当您更改文件类型时,都会在更改发生之前触发一个事件,并将旧类型添加到未使用的文件类型列表中。更改后将发生另一个事件,该事件将从未使用的类型列表中删除新类型。

问题

  1. 所有文件都带有定义的文件类型数组中的第一种类型。在本例中为“jpeg”
  2. 通过更改文件类型,所有其他文件类型都会受到更改!
  3. 当您从 typesUnused 列表中删除文件类型时,types 列表也可能会发生更改!

参见:http://jsfiddle.net/4nyVE/2/

最佳答案

您的问题是您的 typestypesUnused 使用相同的数组 dataTypes 进行初始化。当从 typesUnused 中删除项目时,这也会影响 types,因为它们包含对同一数组的引用。

此时,其他选择中当前选择的选项不再有效(不再在 types 中),因此该值设置为第一个选择。

您最好的选择可能是使用原始数组的副本初始化 typesUnused (myarray.slice(0) 是一种简单的复制方法),例如:

typesUnused: ko.observableArray(dataTypes.slice(0))

关于knockout.js - 手动订阅中的 beforeChange 具有奇怪的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13752779/

相关文章:

knockout.js - 在 knockout.js 中使用可观察数组填充下拉列表

javascript - Knockout 如何更新通过其他函数过滤的 Observable 数组的绑定(bind)?

javascript - knockout 错误 : You cannot apply bindings multiple times to the same element

ruby-on-rails-4 - React-Rails:使用具有翻译 I18n 的组件

knockout.js - “跨度”标签绑定(bind)问题与 knockout

javascript - 如何在 AJAX session 之外更新变量? ( Backbone JS/CoffeeScript)

CoffeeScript 获取函数代码

javascript - knockout JS : `hasFocus` always has Focus

javascript - knockout 验证 throttle

javascript - knockout : Async call not finished before ko. applyBindings()。最好、最简单的做法?