从 Backbone 路由器访问 Backbone 视图中的变量

Access variable in Backbone View from Backbone Router

我的路由器

var AppRouter = Backbone.Router.extend({
        routes: {
            ':*':'home',
            'home' : 'home',
            'home/:a' : 'home',
            '*whatever' : '404'

        },
        home: function (a) {
            document.title = siteTitle + ' - Home';
            homePage = new HomePage;
            homePage.render(a);
        },
        404: function(){
            document.title = siteTitle + ' - 404';
            fofPage = new FoFPage;
            fofPage.render();
        }

    });

我家的风景

var HomePage = Backbone.View.extend({
        initialize: function (options) {
            _.bindAll(this, 'beforeRender', 'render', 'afterRender');
            var _this = this;
            this.render = _.wrap(this.render, function (render) {
                _this.beforeRender();
                render();
                _this.afterRender();
                return _this;
            });
        },

        beforeRender: function () {
            console.log('beforeRender');
        },

        el: $('#indexcontent'),

        template: _.template(homeHTML, {}),

        render: function (a) {
            (a == null) ? Backbone.history.navigate('home'): Backbone.history.navigate('home/' + a);
            console.log('Passed parameter is ' + a);
            this.$el.html(this.template);

        },

        afterRender: function () {
            $('pre code').each(function (i, block) {
                hljs.highlightBlock(block);
            });
            console.log('afterRender');
        }
    });

我正在尝试从路由器中捕获该变量 a 以供查看。但它在我的控制台中显示未定义。我尝试在初始化中摆弄变量 options 但没有成功。 谢谢

var AppRouter = Backbone.Router.extend({
        routes: {
            ':*':'home',
            'home' : 'home',
            'home/:a' : 'home',
            '*whatever' : '404'

        },
        home: function (a) {
            document.title = siteTitle + ' - Home';
            homePage = new HomePage({route: a});
            homePage.render();
        },
        404: function(){
            document.title = siteTitle + ' - 404';
            fofPage = new FoFPage;
            fofPage.render();
        }

    });

查看

var HomePage = Backbone.View.extend({
        initialize: function (options) {
            this.options = options;
            _.bindAll(this, 'beforeRender', 'render', 'afterRender');
            var _this = this;
            this.render = _.wrap(this.render, function (render) {
                _this.beforeRender();
                render(_this.options['route']);
                _this.afterRender();
                return _this;
            });
        },

        beforeRender: function () {
            console.log('beforeRender');
        },

        el: $('#indexcontent'),

        template: _.template(homeHTML, {}),

        render: function (a) {
            (a == null) ? Backbone.history.navigate('home'): Backbone.history.navigate('home/' + a);
            console.log('Passed parameter is ' + a);
            this.$el.html(this.template);

        },

        afterRender: function () {
            $('pre code').each(function (i, block) {
                hljs.highlightBlock(block);
            });
            console.log('afterRender');
        }
    });

当您找到答案时,我会解释为什么您的初始代码不起作用,甚至更多。

为什么传递给 render 不起作用?

因为您使用 underscore's wrap 函数覆盖了 initialize 函数中的 initialize 函数。

它可以工作,但你需要在包装时考虑参数:

this.render = _.wrap(this.render, function(render, a) {
    this.beforeRender();
    render.call(this, a); // here, pass the argument
    this.afterRender();
    return this;
});

另请注意,您不需要 var _this = this,因为您只是替换了 member 函数,调用时会自动应用上下文。 _.bindAll 同样的事情在这里没用。

更简单的方法

包装是不必要的,它只会使 HomePage 视图复杂化,没有任何好处或增加的功能。

您唯一需要的东西:

var HomePage = Backbone.View.extend({
    el: $('#indexcontent'),

您可以忽略 options 参数({}

    template: _.template(homeHTML),

    initialize: function(options) {

如果要传递选项进行初始化,请使用以下模式之一:

        this.options = options || {}; // make sure it's an object.

或者,更好的是,确保它是对象的 副本,具有默认值。

        this.options = _.extend({
            route: "default-value"
        }, options);
    },

    beforeRender: function() {
        console.log('beforeRender');
    },

    render: function(route) {
        this.beforeRender();

在路由器中做重定向,这是他的职责。

        // (a == null) ? Backbone.history.navigate('home'): Backbone.history.navigate('home/' + a);

        console.log('Passed parameter is ' + route || this.options.route);

underscore's _.template函数returns一个函数,所以你需要调用它。

        this.$el.html(this.template());

        this.afterRender();
        return this;
    },

    afterRender: function() {

避免使用全局 jQuery 函数,而更喜欢将搜索范围限定在具有 this.$(selector).

的视图元素及其子元素中
        this.$('pre code').each(function(i, block) {
            hljs.highlightBlock(block);
        });
        console.log('afterRender');
    }
});