使缓存的jQuery对象可用于Backbone中的多个视图

时间:2014-01-23 09:04:40

标签: javascript jquery backbone.js

我正在使用Backbone以及jQuery和requireJS。 我想知道在Backbone中为多个视图提供缓存的jQuery对象的好方法是什么。假设我有 pageView homeView aboutView contactView

在所有这些视图中,我正在操作DOM,目前我需要为以下DOM元素创建一个新的jQuery包装器: .side-left .side -right .page-left .page-right

仅将这些元素包装一次而不是始终创建新实例的最佳方法是什么?

第一个目的是将所有模型添加到集合中并在那里缓存DOM元素。不幸的是,并非所有观点都有模型。我该如何处理?

提前感谢任何建议。

下面的代码显示了我目前如何为一个视图解决它。但其他人无法访问,因为他们没有使用相同的模型。

PageModel.js

define([
    'underscore',
    'backbone'
], function(_, Backbone) {

    var PageModel = Backbone.Model.extend({
        defaults: {
            leftSide: $('#splitlayout div.intro > div.side-left'),
            rightSide: $('#splitlayout div.intro > div.side-right'),
            pageLeft: $('#splitlayout div.page-left'),
            pageRight: $('#splitlayout div.page-right')
        }
    });

    return PageModel;

});

PageView.js

define([
    'jquery',
    'underscore',
    'backbone',
    'global',
    'models/video/VideoModel',
    'views/video/VideoView'
], function($, _, Backbone, Global, VideoModel, VideoView){

    var PageView = Backbone.View.extend({

        el: $("#splitlayout"),

        events: {
            'click .intro-content': 'resetLayout',
            'click .back': 'backToIntro'
        },

        render: function(){

            this.$el.addClass('reset-layout');
            this.model.get('pageLeft').on(Global.transEndEventName, this.onEndTransFn);
            this.model.get('pageRight').on(Global.transEndEventName, this.onEndTransFn);            

        },

        initialize: function() {

            _.bindAll(this);

            this.videoModel = new VideoModel();
            this.VideoView = new VideoView({model: this.videoModel});

            this.render();

        },

        onEndTransFn: function() {

            this.$el.addClass('reset-layout');
            $('html, body').scrollTop = 0;

        },

        backToIntro: function(ev) {

            ev.preventDefault();

            var dir = $(ev.currentTarget).hasClass('back-right') ? 'left' : 'right';

            this.$el.removeClass('open-' + dir);
            this.$el.addClass('close-' + dir);

        },

        resetLayout: function(ev) {

            var layoutClass = $(ev.currentTarget).parent().hasClass('side-left') ? 'open-left' : 'open-right';

            this.$el.addClass(layoutClass)
            this.$el.removeClass('close-right close-left reset-layout');

        }    

    });

    return PageView;

});

1 个答案:

答案 0 :(得分:0)

我会稍微回避你的问题然后说,不要。 IMO视图应该负责它所绑定的元素及其子节点(无论是更多的视图还是标记)。如果你想在视图之间进行通信,你应该使用事件总线(下面使用deafult Backbone,但你可以定义自己的)。所以对于你的情况我会做以下,

var PageView = Backbone.View.extend({
   ...
   initialize: function() {
      this.listenTo(Backbone, Global.transEndEventName, this.onEndTransFn);
      ...
    },

然后无论生成事件的任何视图,

var VideoView = Backbone.View.extend({
   ...
   events: {
      'click div.page-left': 'eventFired',
   },
   eventFired : function(){
      Backbone.trigger(Global.transEndEventName);
   }

你并没有真正展示你的观点的关系,所以这只是一个推断出来的例子。