Не удается прочитать свойство '_listenId' неопределенного при использовании listenTo в представлении

1

Я создаю представление, но оно не отображается на моей странице. Я создаю SPA с позвоночником, и мне нужно, чтобы мой шаблон мог открыть внутри div в моем теле, но я не знаю, в чем моя проблема. Что может быть?

Показать эту ошибку:

Uncaught TypeError: Cannot read property '_listenId' of undefined
at child.Events.(anonymous function) [as listenTo] (http://localhost:9000/bower_components/backbone/backbone.js:222:19)
at child.initialize (http://localhost:9000/scripts/views/RepositoriesView.js:21:12)
at child.Backbone.View (http://localhost:9000/bower_components/backbone/backbone.js:1001:21)
at new child (http://localhost:9000/bower_components/backbone/backbone.js:1566:41)
at child.repositories (http://localhost:9000/scripts/routes/AppRouter.js:46:7)
at child.execute (http://localhost:9000/bower_components/backbone/backbone.js:1265:30)
at Object.callback (http://localhost:9000/bower_components/backbone/backbone.js:1254:16)
at http://localhost:9000/bower_components/backbone/backbone.js:1481:19
at Function.some (http://localhost:9000/bower_components/lodash/dist/lodash.compat.js:4304:25)
at Backbone.History.loadUrl (http://localhost:9000/bower_components/backbone/backbone.js:1479:16)

Мой AppRouter:

/*global Sice, Backbone*/

Sice.Routers = Sice.Routers || {};
Sice.Views = Sice.Views || {};

(function() {
    'use strict';

    Sice.Routers.AppRouter = Backbone.Router.extend({

        //map url routes to contained methods
        routes: {
            "": "repositories",
            "repositories": "repositories",
            "search": "search",
            "starreds": "starreds"
        },

        deselectPills: function() {
            //deselect all navigation pills
            $('ul.pills li').removeClass('active');
        },

        selectPill: function(pill) {
            //deselect all navigation pills
            this.deselectPills();
            //select passed navigation pill by selector
            $(pill).addClass('active');
        },

        hidePages: function() {
            //hide all pages with 'pages' class
            $('div#content').hide();
        },

        showPage: function(page) {
            //hide all pages
            this.hidePages();
            //show passed page by selector
            $(page).show();
        },

        repositories: function() {
            this.showPage('div#content');
            this.selectPill('li.repositories-pill');
            new Sice.Views.RepositoriesView();
        },

        search: function() {
            this.showPage('div#content');
            this.selectPill('li.search-pill');
        },

        starreds: function() {
            this.showPage('div#content');
            this.selectPill('li.starreds-pill');
        }
    });

    Sice.Views.AppView = Backbone.View.extend({

        //bind view to body element (all views should be bound to DOM elements)
        el: $('body'),

        //observe navigation click events and map to contained methods
        events: {
            'click ul.pills li.repositories-pill a': 'displayRepositories',
            'click ul.pills li.search-pill a': 'displaySearch',
            'click ul.pills li.starreds-pill a': 'displayStarreds'
        },

        //called on instantiation
        initialize: function() {
            //set dependency on Sice.Routers.AppRouter
            this.router = new Sice.Routers.AppRouter();

            //call to begin monitoring uri and route changes
            Backbone.history.start();
        },

        displayRepositories: function() {
            //update url and pass true to execute route method
            this.router.navigate("repositories", true);
        },

        displaySearch: function() {
            //update url and pass true to execute route method
            this.router.navigate("search", true);
        },

        displayStarreds: function() {
            //update url and pass true to execute route method
            this.router.navigate("starreds", true);
        }
    });

    //load application
    new Sice.Views.AppView();
})();

Мой вид:

 /*global Sice, Backbone, JST*/

Sice.Views = Sice.Views || {};

(function() {
    'use strict';

    Sice.Views.RepositoriesView = Backbone.View.extend({
        template: JST['app/scripts/templates/RepositoriesView.ejs'],
        tagName: 'div',
        id: 'repositoriesView',
        className: 'page-repositories',
        events: {},

        initialize: function() {
            this.listenTo(this.model, 'change', this.render);
        },

        render: function() {
            this.$el.html(this.template());
        }
    });
})();
Теги:
backbone.js
backbone-events

1 ответ

1
Лучший ответ

Что происходит?

В следующей функции маршрутизатора создается экземпляр нового экземпляра.

repositories: function() {
    this.showPage('div#content');
    this.selectPill('li.repositories-pill');
    new Sice.Views.RepositoriesView(); // <-- here
}, 

Но вы не передаете объект модели, который прослушивает вид.

initialize: function() {
    this.listenTo(this.model, 'change', this.render);
},

Поэтому он вызывает this.listenTo с this.model как undefined.

Какое решение?

Пропустить экземпляр модели

new Sice.Views.RepositoriesView({ model: new MyModel() });

Создание экземпляра модели в представлении

initialize: function() {
    this.model = new MyModel();
    this.listenTo(this.model, 'change', this.render);
},
  • 0
    Теперь он работает без ошибок, но еще не рендерится на содержимое div # :(
  • 0
    @DiogoSoares задает еще один вопрос, специфичный для этой новой проблемы, и включает минимальный воспроизводимый пример .

Ещё вопросы

Сообщество Overcoder
Наверх
Меню