javascript - 主干 listenTo 不会因属性更改而触发

标签 javascript backbone.js

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

为了更好地理解我做了一个简单得多的示例,它只包含一个模型、一个 View 和设置 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. 一些模型初始化
  3. 应用 View 初始化
  4. SomeModel onNameChanged
  5. SomeModel setName

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

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

最佳答案

调用 set 不一定会改变任何东西。例如,这个:

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

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

您模型的initialize 设置名称:

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

'change:name' 处理程序由该点绑定(bind),因此 onNameChanged 将被调用并且 hasName 将设置为 是的

然后 View 被构建,它的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
}

然后调整 View (及其模板)以处理“无名称”的情况。

关于javascript - 主干 listenTo 不会因属性更改而触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31493589/

相关文章:

javascript - 如何使放置在 IFRAME 内的链接在父窗口中打开

javascript - 在 HTML 表单中使用自动生成的(即随机的)ID

backbone.js - Marionette 路由器未触发路线上的 Controller 方法

javascript - IE JS 兼容性 - 在 FF 中工作?

javascript - 仅当我们在 Chrome 浏览器中按 F12(开发者工具)时, Highcharts 才会显示数据

javascript - 在 Backbone/Require 应用程序中使用 Router 和 ineriew 渲染嵌套 View

php - 我如何控制主干项目的 PHP、 header 等版本的缓存?

javascript - this.$el.on Backbone.Marionette

javascript - 随机背景图像未加载

javascript - Turn.js 中的哈希导航