【问题标题】:Backbone listenTo does not fire for property changeBackbone listenTo 不会因属性更改而触发
【发布时间】:2015-07-18 17:17:28
【问题描述】:

我是 Backbone 的新手,我有一些代码可以监听属性更改并触发函数。我在网上看到的关于如何使用 listenTo 的所有内容似乎都涵盖了这种确切的情况,所以我不知道我忽略了什么。

为了更好地理解,我制作了一个简单得多的示例,它只包含一个模型、一个视图并设置了 listenTo。在那个较小的样本中仍然会出现问题。

我已经输入了一些代码来记录哪些函数被触发以及以什么顺序被触发。当我看到运行此代码时几乎是我所期望的顺序,除了永远不会调用 onSomethingChanged。

var AppView = Backbone.View.extend({
    initialize: function(){
        this.listenTo(this.model, 'change:hasName', this.onSomethingChanged);

        $('#steps').append('<li>AppView initialize</li>');
        this.model.setName('Test Name');
    },
    onSomethingChanged: function(){
        $('#steps').append('<li>AppView onSomethingChanged</li>');
    }
});

var SomeModel = Backbone.Model.extend({
    initialize: function(){
        this.bind('change:name', this.onNameChanged, this);
        this.set({'name': 'Nothing'});

        $('#steps').append('<li>SomeModel initialize</li>');
    },
    onNameChanged: function(status, name){
        this.set({'hasName': name != null});

        $('#steps').append('<li>SomeModel onNameChanged</li>');
    },
    setName: function(name){
        this.set({'name': name});

        $('#steps').append('<li>SomeModel setName</li>');
    }
});

$(function(){
    window.app = new AppView({model: new SomeModel()});
});

我在这里设置了一个小提琴:https://jsfiddle.net/hamveefz 它显示顺序如下:

  1. SomeModel onNameChanged
  2. SomeModel 初始化
  3. AppView 初始化
  4. SomeModel onNameChanged
  5. SomeModel 设置名称

我假设在 SomeModel 的 onNameChanged 函数中,它使用 hasName 属性执行“this.set”会自动导致调用 hasName 更改的侦听器。

有人可以向我解释我在哪里出错了吗?

【问题讨论】:

    标签: javascript backbone.js


    【解决方案1】:

    致电set 不一定会改变任何事情。例如,这个:

    model.set('property', model.get('property'));
    

    不会触发 'change' 事件,因为它实际上并没有做任何事情。

    您的模型的initialize 设置名称:

    this.set({'name': 'Nothing'});
    

    'change:name' 处理程序由该点绑定,因此将调用 onNameChanged 并将 hasName 设置为 true

    然后视图被构建,它的initialize 将:

    this.listenTo(this.model, 'change:hasName', this.onSomethingChanged);
    this.model.setName('Test Name');
    

    您认为setName 应该触发'change:hasName' 事件,但它不会。 hasName 属性此时已经是 true 并且您将执行 set('hasName', true) 所以它不会改变。

    您最好将name 保留为nullundefined,直到它真正被设置为止。您将从模型的 initialize 中删除 this.set({'name': 'Nothing'}); 并添加:

    defaults: {
        name: null,
        hasName: false
    }
    

    然后调整到视图(及其模板)来处理“无名”的情况。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-01-27
      • 1970-01-01
      • 2016-04-06
      • 1970-01-01
      • 2017-09-14
      • 1970-01-01
      • 2021-09-18
      • 1970-01-01
      相关资源
      最近更新 更多