从骨干路由器访问Backbone View中的变量

时间:2016-11-05 23:32:11

标签: javascript jquery backbone.js

我的路由器

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,但没有运气。 感谢

2 个答案:

答案 0 :(得分:2)

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

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

因为您使用underscore's wrap函数覆盖render函数中的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,因为您只需更换成员功能,并且在调用时会自动应用上下文。 _.bindAll同样的事情在这里没用。

更简单的方法

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

您唯一需要的东西:

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

您可以忽略选项参数({}

    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函数返回一个函数,因此您需要调用它。

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

        this.afterRender();
        return this;
    },

    afterRender: function() {

避免使用全局jQuery函数,并希望使用this.$(selector)将搜索范围限定为view元素及其子元素。

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

答案 1 :(得分:1)

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');
        }
    });