backbone 无法读取未定义的 属性 'push'

backbone Cannot read property 'push' of undefined

我正在使用 Backbone,当我生成视图时出现错误 Cannot read 属性 'push' of undefined”。错误行是 "self.subViewsReservas.push(new ReservaView({"在推送中。

    ReservaCollectionView = Backbone.View.extend({

initialize: function () {
    if (Session.get('authenticated') && Session.get('authenticated') !== false) {
        this.paginacionVista = new PaginacionReservasView({
            collection: this.collection,
            el: '.paginacionReservas',
            reservasPagina: 5,
        });
        this.buscadorVista = new BuscadorView({
            el: 'div.buscador-reservas',
            //Pasamos la colección oficinas ya que hará las veces del conjunto de oficinas retornadas por el servidor
            collection: new OficinasCollection(oficinas),
        });
    }
    else {
    }
},
render: function () {
    var self = this;
    this.template = _.template($('#divReservaTpl').html(), {});
    self.$('.contenedor-reservas').empty();
    self.collection.each(function (reserva, index) {
        self.$('.contenedor-reservas').append(self.template({'data': reserva.toJSON()}));
    });
    this.collection.each(function (reserva, index) {
      this.subViewsReservas = [];
          self.subViewsReservas.push(new ReservaView({
              el: '#' + reserva.get('Idreserva'),
              model: reserva
          }));
    });
    this.collection.each(function (reserva, index) {
        //Limite de la paginacion 5 limite arbitrario
        if (index < 5) {
            //Lo Marcamos como visible y actualiazamos la paginación
            self.collection.get(reserva.get('Idreserva')).set({'Visibilidad': true});
        }
    });

    this.paginacionVista.render();

    return this;
},

});

AppView = Backbone.View.extend({
    initialize : function(){
            var self = this;

            self.usu = new UsuarioModel();
            self.usu.fetch({
                success: function (model){
                    Session.fetch({
                        success : function (){

                            Session.set('nombre',model.get('Nombre'));
                            Session.set('apellidos',model.get('Apellidos'));
                            Session.set('puntos_club',model.get('Puntosclub'));

                            self.render();
                        }
                    });

                    self.sideBar = new SideBarView({
                        el : '.sidebar',
                        model: model
                    });
                    self.sideBar.markOption('mis-reservas');
            AppView = Backbone.View.extend({
    initialize : function(){
            var self = this;

            self.usu = new UsuarioModel();
            self.usu.fetch({
                success: function (model){
                    Session.fetch({
                        success : function (){

                            Session.set('nombre',model.get('Nombre'));
                            Session.set('apellidos',model.get('Apellidos'));
                            Session.set('puntos_club',model.get('Puntosclub'));

                            self.render();
                        }
                    });

                    self.sideBar = new SideBarView({
                        el : '.sidebar',
                        model: model
                    });
                    self.sideBar.markOption('mis-reservas');
                },
                error : function (){
                    document.location = '/mygoldcar/login';
                }
            });            

            this.listenTo(Session, 'change', self.update);        
    },
    render : function(){
            var self = this;
            var reservas = new ReservasCollection();
            reservas.fetch({
                success: function (collection){
                    if ( typeof collection.models[0].get('error') == 'undefined' || !collection.models[0].get('error')) {
                        var listRes = new ReservaCollectionView({
                            el : '.reservas-list',
                            collection: collection   
                        });
                        listRes.render();

                        var popoverModel = new Popover();
                        popoverModel.setData(collection.models[0].get('kilometraje_ilimitado'), collection.models[0].get('duracion'));

                        self.popover = new PopoverView({
                            el: 'body',
                            model: popoverModel
                        });

                        self.popover.establecerPopover();
                    }
                    else document.location = '/mygoldcar' + self.urlLang(lang) + '/mi-cuenta/#msg/1';                    
                },
                error: function () {
                    document.location = '/mygoldcar' + self.urlLang(lang) + '/mi-cuenta/#msg/1';                    
                }
            });
    },
        update: function() {
            var self = this;
            self.sideBar.update(Session.get('nombre'),Session.get('apellidos'),Session.get('puntos_club'));   
            self.$el.find('.nombre-usuario').text(Session.get('nombre'));            
        },
        updatePoints: function() {
            var self = this;
            self.usu.fetch({
                success: function (model){
                    Session.set('puntos_club',model.get('Puntosclub'));
                }
            });
        }   
});    },
                error : function (){
                    document.location = '/mygoldcar/login';
                }
            });            

            this.listenTo(Session, 'change', self.update);        
    },
    render : function(){
            var self = this;
            var reservas = new ReservasCollection();
            reservas.fetch({
                success: function (collection){
                    if ( typeof collection.models[0].get('error') == 'undefined' || !collection.models[0].get('error')) {
                        var listRes = new ReservaCollectionView({
                            el : '.reservas-list',
                            collection: collection   
                        });
                        listRes.render();

                        var popoverModel = new Popover();
                        popoverModel.setData(collection.models[0].get('kilometraje_ilimitado'), collection.models[0].get('duracion'));

                        self.popover = new PopoverView({
                            el: 'body',
                            model: popoverModel
                        });

                        self.popover.establecerPopover();
                    }
                    else document.location = '/mygoldcar' + self.urlLang(lang) + '/mi-cuenta/#msg/1';                    
                },
                error: function () {
                    document.location = '/mygoldcar' + self.urlLang(lang) + '/mi-cuenta/#msg/1';                    
                }
            });
    },
        update: function() {
            var self = this;
            self.sideBar.update(Session.get('nombre'),Session.get('apellidos'),Session.get('puntos_club'));   
            self.$el.find('.nombre-usuario').text(Session.get('nombre'));            
        },
        updatePoints: function() {
            var self = this;
            self.usu.fetch({
                success: function (model){
                    Session.set('puntos_club',model.get('Puntosclub'));
                }
            });
        }   
});

collection.each里面,this指向集合。所以 属性 subViewsReservas 添加到它,而不是视图实例。当您尝试像 self.subViewsReservas.push 一样访问它时,self 指向没有 subViewsReservas 属性 的视图实例,因此出现错误。

像您所做的那样在 each 中初始化一个数组并没有太大作用,因为它会在每次调用回调时重置。

您应该在 initialize 方法中对其进行初始化,这是 初始化 事物的正确位置,其中 this 将正确指向视图实例如下图

initialize: function () {
  this.subViewsReservas = [];
}

出于某种原因,如果您希望每次都重置该集合,您可以通过将其作为第二个参数传递给每个 like 来更改要查看的上下文:

this.collection.each(function (reserva, index) {
  this.subViewsReservas = [];
      self.subViewsReservas.push(new ReservaView({
          el: '#' + reserva.get('Idreserva'),
          model: reserva
      }));
}, self); // <--- makes view the context of callback,
          // both 'self' and 'this' will refer to view