如何编写防弹骨干js管理器?(或修复此示例中的委托事件)

How to write a bulletproof Backbone js manager? (or fix delegated events in this example)

本文关键字:事件 防弹 何编写 js 管理器      更新时间:2023-09-26

我正在编写一个应用程序,该应用程序将由具有不同经验的团队扩展,因此我试图限制Backbone的灵活性,以便提供一种一致的方式来构建我们的代码。 为此,我编写了一个简单的外观,将类和实例隐藏在get/set函数后面,这样类/实例就不会被无意中覆盖,我们使用局部变量与全局变量,我们的代码保持更漂亮,维护更少。

到目前为止,我的原型代码运行良好,但有一个例外 - 在子类化视图中,"events"属性不会委派事件。 如果你看到什么坏了,我将不胜感激! 如果您知道一种更好的方法来组织代码以实现相同的目的,我也对此持开放态度!

谢谢!

在 http://jiggler.media.mit.edu:8008/projects/2147302/?mode=player 处运行的代码的临时示例,以及位于 http://jiggler.media.mit.edu/adam/scratchr2/static/js/project.js 处的子类化视图。 运行代码中有相当多的内容不相关,所以我提取了下面的相关逻辑。

运行主干 0.9.2、下划线 1.3.3 和 jQuery 1.7.1

// Facade factory - creates an interface for working with views
window.scratch={};
scratch.createBackboneManager=function(type,optionsObj){
  if (!type || !Backbone[type]) throw 'type required to add a backbone type (e.g., Model, View) to scratch';
  if(scratch[type]) throw 'scratch.'+type+' already exists';
  scratch[type]=(function(){
    var classes={};
    function create(name,classObj){
      if (classes[name]) throw type+' '+ name + ' already exists.';
      if (name[0].toUpperCase()!==name[0]) throw type+' names must be upper case. "'+name+'" starts lower case.';
      return classes[name]=(function(){
        var instances={},
            Klass = (classes[classObj.extendsClass]||Backbone[type]).extend(classObj);
        function createInstance(name,options){
          if (instances[name]) throw 'Instance '+ name + ' already exists';
          if (name[0].toLowerCase()!==name[0]) throw 'Instance names must be upper case. "'+name+'" starts upper case.';
          return instances[name]=new Klass(options);
        };
        function getInstance(name){
          return instances[name];
        };
        return $.extend(Klass,{getInstance:getInstance,createInstance:createInstance}) // return the Class with simple instance management methods.
      })();
    };
    function get(name){
      return classes[name]||undefined;
    };
    return $.extend({create:create,get:get},optionsObj);
  })();
};
// create managers
scratch.createBackboneManager('View');
scratch.createBackboneManager('Model');
// create a model
scratch.Model.create('Project',{
  defaults: {// current project
    owner: null, // instance of user?
    parentId: null,
    title: 'Untitled',
    isPrivate: false,
  }
}).createInstance('project',{
  owner: 'foo',
  viewing_user:'bar',
  title:'baz',
  id: '12345', 
});
// create a view
scratch.View.create('Global_UI',{
  initialize:function(){
    var self=this;
    $(document).ready(function(){self.render()});
  },
}).createInstance('global_ui');
// subclass the view and add events
scratch.View.create('Showcase',{
  extendsClass:'Global_UI',
  events: {
    "mouseover .see-inside"         : 'alertSee',
  },
  alertSee:function(e){alert(e)},
}).createInstance('showcase',{
  el:document.getElementById('project'),
  model:scratch.Model.get('Project').getInstance('project')
});

如果没有 jsfiddle 或类似的东西中的工作示例,诊断起来非常复杂,但你确定你不想要这个......

Klass = (classes[classObj.extendsClass]||Backbone[type]).extend(classObj);

。是这个?...

Klass = (
  classes[ classObj.extendsClass ] || Backbone[ type ]
).extend( classObj );

不要忘记将实例创建放在 $(document(.ready(( 调用中,否则 getElementById(( 调用将不存在这些元素。

咚!