Триггер модели Backbone.js изменяется, только если снова вызывается model.on

Это мой первый пост, так что будьте любезны ;) Я пытаюсь создать образец приложения Backbone+requireJS и наткнулся на странную проблему. В моих представлениях функция инициализации, которую я привязываю к событию изменения моделей,

this.model.on("change", this.change());

Событие запускается правильно, когда данные загружаются, и все в порядке. На мой взгляд, я также привязываюсь к событию клика. При щелчке я пытаюсь изменить одно из свойств и надеялся на событие изменения, но оно так и не произошло.

Я пробовал кое-что, рекомендованное здесь, в stackoverflow (здесь, здесь, и там), но безуспешно.

В глубине души я чувствую, что это связано с привязкой событий. Когда я попытался снова привязать модели к событию изменения внутри обратного вызова клика, он начал работать. Итак, теперь я сижу здесь и я, хм, в замешательстве. Может ли кто-нибудь пролить свет на этот вопрос?

Мой вид:

define(
[
  'jquery',
  'underscore',
  'backbone',
  'text!templates/news/newsListItem.html'
 ],
 function($, _, Backbone, newsListItemTemplate)
 {
    var NewsListItemViewModel = Backbone.View.extend({
        tagName: 'li',
        events: {
            "click a" : "onLinkClick"
        },
        initialize: function(){
            this.model.on("change", this.changed());
        },
        render: function()
        {
            this.$el.html(_.template(newsListItemTemplate, this.model.toJSON()));
        },
        changed: function()
        {
            this.render();
            console.log("changed");
        },
        //GUI functions
        onLinkClick: function(e)
        {
            console.log("click!");
            this.model.toggle();
            this.model.on("change", this.changed());

        }

    });

    var init = function(config){
        return new NewsListItemViewModel(config);
    }

    return {
        init : init
    }
 }

);

Моя модель:

define(
['jquery', 'underscore', 'backbone'],
function($, _, Backbone){

    var NewsListItemModel = Backbone.Model.extend({
        toggle: function() {
            this.set('done', !this.get('done'));
            this.trigger('change', this);
        }
    });

    var init = function(data)
    {
        return new NewsListItemModel(data);
    }

    return {
        init: init,
        getClass: NewsListItemModel
    };
}

);

Спасибо за любой вклад :)


person user3485150    schedule 01.04.2014    source источник


Ответы (1)


Во-первых, в качестве обработчика событий следует использовать функцию, а не ее результат. Следовательно, измените строку на эту:

this.model.on("change", this.changed.bind(this));

В нынешнем виде вы фактически запускаете функцию this.changed() только один раз и назначаете ее результат (то есть undefined, поскольку функция не имеет оператора return) в качестве обработчика события change модели.

Во-вторых, вы не должны перепривязывать этот обработчик в onLinkClick: однажды связанный, он останется здесь. Похоже, вместо этого более уместно trigger это событие:

onLinkClick: function(e)
{
  console.log("click!");
  this.$el.toggle();
  this.model.trigger('change');
}
person raina77ow    schedule 01.04.2014
comment
Спасибо дружище, сработало! Код в onLinkClick содержит мой код отладки, перепривязка была только проверкой, чтобы проверить, работает ли перепривязка. Я также сейчас смотрю на todos, и там они связываются в init как парные: this.listenTo (this.model, 'изменить', this.render); это рекомендуемый способ привязки к модели? - person user3485150; 01.04.2014