更新阵列时模型的更改事件不会触发?

fan*_*ncy 5 javascript jquery coffeescript backbone.js

使用backbone.js ......

@model.bind 'change', ()-> console.log 'updated'

addIndex = (index) =>
    array = @model.get('array')
    array.push index
    @model.set
        array: array
Run Code Online (Sandbox Code Playgroud)

这会完美更新模型,但不会触发更改事件.有谁知道为什么从我发布的内容?

编辑:

我添加了这个并触发了change事件:

@model.set
    test: ''

num = 0
setInterval ()=>
    num++
    @model.set
    test: num
, 3000
Run Code Online (Sandbox Code Playgroud)

我添加了这个并且它不会触发更改事件:

@model.set
    test: []

num = 0
setInterval ()=>
    console.log 'testupdate'
    num++
    test = @model.get('test')
    test.push num
    @model.set
        test: test
, 3000
Run Code Online (Sandbox Code Playgroud)

Edw*_*ith 8

布莱恩的答案原因很棒!

想要提供另一种方法来获得你想要的东西,而不是将其归零或克隆数组.

只需自己手动触发更改:

addIndex = (index) =>
    array = @model.get('array')
    array.push index
    @model.trigger('change:array',@model, array)
Run Code Online (Sandbox Code Playgroud)


jos*_*ire 7

由于您正在设置引用的对象,请使用_.clone().

test = _.clone @model.get('test')
test.push num
@model.set test: test
Run Code Online (Sandbox Code Playgroud)

由于您不再使用引用的对象/数组来设置自身,因此如果更改事件已更改,它将触发更改事件.


Bri*_*sio 6

问题是您使用现有值设置值.看一下源代码:

http://documentcloud.github.com/backbone/docs/backbone.html#section-33

当你调用set它时有一个保护子句,以确保你没有设置相同的值(以避免事件循环).在您的情况下,您将获得阵列,修改它并再次设置它,这不会触发您的事件.

当然,当你set test: {},它是一个带有新物体的新物品时,它会再次触发.如果你真的想要触发事件,你可以将它设置为null,然后将其设置为空数组,然后再次设置为填充的数组...


Ahr*_*got 6

更改对象或数组时,另一种方法是在设置新的更新值之前静默取消设置属性.像这样的东西:

(function() {
    var arr, model = new Model();

    model.set( "arrayProp", [1, 2, 3] );
    arr = model.get( "arrayProp" );
    arr.push( 4 );

    model.unset( "arrayProp", { silent: true } );
    model.set( "arrayProp", arr );
})();
Run Code Online (Sandbox Code Playgroud)

通过设置silent: true取消设置prop时,change事件将仅触发一次(当set()调用方法并且属性已更新时).

这样做或手动调用事件之间没有什么区别,这只是个人偏好的问题.

  • 我更喜欢这个选项 - 这样Backbone使用默认参数激发所有事件变体(`change`和`change:arrayProp`),因此它不会破坏任何侦听器. (2认同)