магистраль requirejs: проблема с областью действия

#backbone.js #requirejs

#backbone.js #requirejs

Вопрос:

У меня есть 2 представления, одно из которых представляет собой список «временных дорожек», а другое — форму для создания временных дорожек, к первому из которых прикреплена коллекция. Вторая, форма timetraks, определяет функцию «создать», которая ссылается на первую, чтобы повторно отобразить представление timetraks после создания нового timetrak.

timetracks код:

 define(['backbone','collections/timetracks', 'views/timetracks/item'], function(Backbone, instanceTimeTracksCollection, TimeTrackView){
    var TimeTrackGrid = Backbone.View.extend({
        //......
    });
    return TimeTrackGrid;

});
  

Код формы:

 define(['backbone', 'collections/timetracks'], function(Backbone, instanceTimeTracksCollection){
    //...............
    //next comes my issue:
    create: function(){
        instanceTimeTracksCollection.create(indexed_array,{
            success: function(model, response) {
                console.info('model created, response = ',response);
                // timeTracksGrid is out of scope, timeTracksGrid would be an instance of timetracks.
                timeTracksGrid.render();
            },
            error: function(error){
                console.info('error=',error);
            },
            wait:true
        });
    }

});
  

… и, наконец, у меня есть app.js где определены экземпляры обоих представлений:

 requirejs(['backbone','views/timetracks/new','views/timetracks/list'],
    function(Backbone, newTimeTrackForm, timeTracksGrid) {
        var grid = new timeTracksGrid();
        var formView = new newTimeTrackForm();
    });
  

Как я мог бы отобразить представление timetracks после создания нового timetrack?

**************************** ОБНОВИТЬ *************************************

Это моя новая версия кода. Проблема сейчас в том, что «this.listenTo (this.collection, «добавить», this.render);» перекрывается с «this.collection.извлечение «. В результате записи timetracks отображаются несколько раз.

 // timetracks view
define(['backbone','collections/timetracks', 'views/timetracks/item'], function(Backbone, timeTracksCollection, TimeTrackView){
    var TimeTrackGrid = Backbone.View.extend({
            //....
            initialize: function(){
                _.bindAll(this, 'render', 'generateTimeTracks', 'appendTimeTrack');
                this.listenTo(this.collection, "add", this.render);
                this.render();
            }
            render: function(){
                $(this.el).html("<table border='1'></table>");
                this.collection.fetch({
                    success: this.generateTimeTracks
                });
           },
           generateTimeTracks : function(){
                var self = this;
                _(this.collection.models).each(function(item){ 
                    self.appendTimeTrack(item);
                }, this);
           },
           appendTimeTrack: function(item){
                var timeTrackView = new TimeTrackView({
                    model: item
                });
                $('table', this.el).append(timeTrackView.render().el);
           }

    }
  

Некоторые другие изменения:

  • на app.js вместо того, чтобы делать {model: MyCollection}, как вы предложили, я делаю {collection: MyCollection}
  • мой код формы создает новую модель, вызывая this.collection.create

Еще раз спасибо!

Комментарии:

1. у меня есть несколько вопросов: 1) «timetrack» — это вид timetrack или модель? 2) вам нужно перехватить событие, которое должно быть создано или отображено? 3) есть ли у вас возможность обновить метод render() в представлениях и можно ли использовать пользовательские события?

2. @Evgeniy, 1) «timetracks» — это представление. 2) Извините, я не понимаю этого вопроса 3) Я думаю, что мог бы…

Ответ №1:

Другим решением было бы создать представления и вашу коллекцию отдельно.

Затем в вашем app.js вы могли бы передать коллекцию в оба представления. В функции инициализации TimeTrackGrid вы должны прослушать событие «добавить» моделей в коллекции. Когда такое событие запускается, вы должны отобразить представление.

В методе создания вашего представления формы вы можете добавить данные в свою коллекцию. Таким образом, ваши представления не должны ничего знать друг о друге, что лучше соответствует разделению модели и представления.

Таким образом:

 //the grid view
define(['backbone', 'collections/timetracks', 'views/timetracks/item'], function (Backbone, instanceTimeTracksCollection, TimeTrackView) {
    var TimeTrackGrid = Backbone.View.extend({
        initialize: function () {
            //start listening to models being added
            this.listenTo(instanceTimeTracksCollection, "add", this.render)
        },
        render: function () {
            //render your view
            return this;
        }
    });
    return TimeTrackGrid;

});


//and the form view
define(['backbone', 'collections/timetracks'], function (Backbone, instanceTimeTracksCollection) {
    //...............
    //next comes my issue:
    create: function () {
        var data = //get the data from the form
            instanceTimeTracksCollection.add(data) //if you have defined a model on your collection, backbone will automatically instantiate the model
    }
});


//and you app -> notice the reference to the collection definition
requirejs(['backbone','views/timetracks/new','views/timetracks/list', 'collections/timetrackcollection'],
    function(Backbone, newTimeTrackForm, timeTracksGrid) {
        var instanceTimeTracksCollection = new TimeTracksCollection();
        var grid = new timeTracksGrid({model : instanceTimeTracksCollection});
        var formView = new newTimeTrackForm(model : instanceTimeTracksCollection);
    });
  

РЕДАКТИРОВАТЬ=========================================================

извлеките конфигурацию здесь

 requirejs(['backbone','views/timetracks/new','views/timetracks/list'],
    function(Backbone, newTimeTrackForm, timeTracksGrid) {
        var grid = new timeTracksGrid();
        var formView = new newTimeTrackForm();
        var collection = new Collection();
        collection.fetch()
    });
  

измените свой вид на:

 define(['backbone','collections/timetracks', 'views/timetracks/item'], function(Backbone, timeTracksCollection, TimeTrackView){
    var TimeTrackGrid = Backbone.View.extend({
            //....
            initialize: function(){
                _.bindAll(this, 'render', 'generateTimeTracks', 'appendTimeTrack');
                // maybe backbone does not fire the add event after fetch
                // I believe it does, but I might be mistaken. You will have to look         that up
                this.listenTo(this.collection, "add", this.render);
                this.render();
            }
            //model is passed to the render method by backbone
            render: function(model){
                $(this.el).html("<table border='1'></table>");
                $('table', this.el).append(new TimeTrackView({model : model}).render().el);
           },
           //unused now
           generateTimeTracks : function(){
                var self = this;
                // backbone has underscore build in
                // so use this instead
                this.collection.each(function(item){
                     //do something with item
                }
                _(this.collection.models).each(function(item){ 
                    self.appendTimeTrack(item);
                }, this);
           },
           //unused now
           appendTimeTrack: function(item){
                var timeTrackView = new TimeTrackView({
                    model: item
                });
                $('table', this.el).append(timeTrackView.render().el);
           }

    }
  

Комментарии:

1. спасибо за ваш ответ и извините за мой поздний ответ, я был очень занят другими вещами, и теперь я возвращаюсь к своим первым шагам на node.js . Я последовал вашему совету и создаю экземпляр конструктора отдельно. К сожалению, теперь я столкнулся с новой проблемой с событием «Добавить». Проблема в том, что при отображении представления timetracks, когда это происходит, я ИЗВЛЕКАЮ коллекцию моделей с сервера, выборка представляет собой своего рода наложение запущенных событий «добавить». Выше приведено новое обновление моего кода.

2. итак, при добавлении ead вы получите всю коллекцию? Мне это не кажется правильным. смотрите mmy edit для обновления.