在Backbone中实现memoize风格的模块加载器

时间:2011-11-03 17:12:41

标签: javascript backbone.js

开始重构我的Backbone应用程序,引用Bocoup撰写本文:http://weblog.bocoup.com/organizing-your-backbone-js-application-with-modules

我在初始化模块中定义的视图时遇到了问题。

请参阅此jsfiddle:http://jsfiddle.net/nicksergeant/8L6JX/

我的application.js:

// Memoizing technique from http://weblog.bocoup.com/organizing-your-backbone-js-application-with-modules
var sidepros = {
    // Create this closure to contain the cached modules
    module: function() {
        // Internal module cache.
        var modules = {};

        // Create a new module reference scaffold or load an
        // existing module.
        return function(name) {
            // If this module has already been created, return it.
            if (modules[name]) {
                return modules[name];
            }

            // Create a module and save it under this name
            return modules[name] = { Views: {} };
        };
    }()
};

// Using the jQuery ready event is excellent for ensuring all 
// code has been downloaded and evaluated and is ready to be 
// initialized. Treat this as your single entry point into the 
// application.
jQuery(function($) {

    if ($('body').hasClass('apply')) {
        sidepros.app = new sidepros.module('apply').Views.AppView();
    }

});

模块,apply.js:

(function(Apply) {

    App = sidepros.app;

    Apply.FieldModel = Backbone.Model.extend({
        group: null
    });
    FieldView = Backbone.View.extend({
        initialize: function() {
            this.model = new FieldModel({
                group: $(this.el).parents('div.group').attr('id')
            });
            this.model.view = this;

            this.$tooltip = $('div.tooltip', $('#' + this.model.get('group')));
        },
        events: {
            'focus': 'focused',
            'blur' : 'blurred',
            'keyup': 'updateTooltip'
        },
        focused: function() {
            App.$tooltips.hide();
            this.$tooltip.show();
        },
        blurred: function() {
            App.$tooltips.hide();
        },
        updateTooltip: function() {
            if (this.model.get('group') == 'name') {
                short_name = $.trim(App.$first_name.val() + ' ' + App.$last_name.val().charAt(0));
                if (short_name !== '') {
                    short_name = ': ' + short_name;
                }
                App.$name_preview.text($.trim(short_name));
            }
        }
    });

    AppView = Backbone.View.extend({
        el: '#app',

        initialize: function(opts) {
            $('input, select, textarea', this.el).each(this.addField);

            this.$first_name   = $('input#id_first_name', this.el);
            this.$last_name    = $('input#id_last_name', this.el);
            this.$name_preview = $('strong#name-preview', this.el);
            this.$tooltips     = $('div.tooltip', this.el);
        },
        addField: function() {
            model = new FieldView({ el: this });
        }
    });

    Apply.Views = {
        'AppView': AppView,
        'FieldView': FieldView
    };

})(sidepros.module('apply'));

尝试初始化AppView时:

sidepros.app = new sidepros.module('apply').Views.AppView();

我收到错误:

Uncaught TypeError: Object #<Object> has no method '_configure'

1 个答案:

答案 0 :(得分:2)

您收到该错误是因为Javascript对构造函数的上下文感到困惑。如果您单步进入AppView构造函数,则上下文为Apply.Views,这意味着尚未调用new运算符。

要消除该错误,您需要执行以下操作之一:

    var appView = sidepros.module('apply').Views.AppView;
    sidepros.app = new appView();

OR

    sidepros.app = new (sidepros.module('apply').Views.AppView)();

除此之外,我不确定你要做什么。您的jsFiddle中没有inputselecttextarea个节点,因此我无法确定您的下一个问题是什么。

此外,这句话model = new FieldView({ el: this }):对我来说真的很奇怪。为什么要在addField函数中将模型设置为您的视图?

我认为需要一个新的jsFiddle来进一步调试。