在视图中使用listenTo时,无法读取未定义的属性'_listenId'

时间:2017-06-06 17:03:48

标签: javascript backbone.js backbone-events

我正在创建一个视图,但它没有在我的页面中呈现。 我正在建立一个带骨干的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());
        }
    });
})();

1 个答案:

答案 0 :(得分:1)

发生了什么?

在以下路由器功能中,您将实例化一个新的View实例。

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.listenTothis.model称为undefined

解决方案是什么?

传递模型实例

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

在视图中创建模型实例

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