【问题标题】:Check to see if something is a model or collection in backbone js检查某些东西是否是主干js中的模型或集合
【发布时间】:2012-04-29 13:05:16
【问题描述】:

当您覆盖主干同步时,模型/集合 .save()/fetch() 都使用相同的主干同步方法,那么检查 Backbone.sync 接收的是模型还是模型集合的最佳方法是什么?

举个例子:

Backbone.sync = function(method, model, options){
  //Model here can be both a collection or a single model so
 if(model.isModel()) // there is no isModel or isCollection method
}

我想我正在寻找一种“安全”的最佳实践,我当然可以检查只有模型或集合具有的某些属性或方法,但这似乎很老套,难道不应该有更好的明显方法吗?而且可能是我找不到它。

谢谢!

【问题讨论】:

    标签: javascript backbone.js


    【解决方案1】:

    你也可以像这样尝试instanceof

    Backbone.sync = function(method, model, options) {
      if (model instanceof Backbone.Model) {
        ...
      } else if (model instanceof Backbone.Collection) {
        ...
      }
    }
    

    【讨论】:

      【解决方案2】:

      @fiskers7 的回答适用于深度扩展:

              var Item = Backbone.Model.extend({
                  className : 'Item',
                  size :10
              });
      
              var VerySmallItem = Item.extend({
                  size :0.1
              });
      
              var item = new Item();
              var verySmall = new VerySmallItem();
      
              alert("item is Model ?" + (item instanceof Backbone.Model)); //true
              alert("verySmall is Model ?" + (verySmall instanceof Backbone.Model)); //true
      

      【讨论】:

        【解决方案3】:

        这同样是 hackish,但是 Backbone 集合有一个模型属性,而一个模型没有——它本身就是一个模型。

        也许更安全的方法是 model.toJSON() 并查看结果是对象还是数组。无论如何,您可能会在自定义 Backbone.sync 中使用 model.toJSON(),因此尽管这在计算上相当昂贵,但无论如何都会发生。

        【讨论】:

        • 赞成,因为我昨天在一些快速编码中检查了length 属性(仅收藏...?!?)!相比之下,查看model 非常出色。哈哈。
        • 你们不应该指望这样的东西,因为它们将来可能会改变并破坏您的代码。按照描述使用 instanceof 关键字:)
        【解决方案4】:

        我不完全确定我对此的感受,因为它看起来有点骇人听闻,但我无法完全想到为什么现在它会非常糟糕。

        绝对简单,比“instanceof”检查更快(我假设您不会在对象上命名任何其他函数“isBBModel/Collection”?)

        Backbone.Model.prototype.isBBCollection = function() { return false; }
        Backbone.Model.prototype.isBBModel = function() { return true; }
        Backbone.Collection.prototype.isBBCollection = function() { return true; }
        Backbone.Collection.prototype.isBBModel = function() { return false; }
        

        【讨论】:

          【解决方案5】:

          你可以这样做。

          Backbone.Model.prototype.getType = function() {
              return "Model";
          }
          
          Backbone.Collection.prototype.getType = function() {
              return "Collection";
          }
          
          if(model.getType() == "Model") {}
          if(model.getType() == "Collection"){}
          

          【讨论】:

          • 这是一个非常糟糕的主意,当应用程序变得更复杂时几乎不可能维护。如果一个对象需要一个 getType() 方法来讨论 Car 类型而不是 Backbone 对象类型,会发生什么?
          • @NicolasZozol 不同意。我不明白这有多难维护,第二点简直是不公平的。您可以随意调用上述方法。比如getBackboneObjectType,绝对不会引起命名冲突。
          • 这不好的原因是它要求实现者跟踪包含在第 3 方库中的对象类型,并且每次将新类型引入到未来版本的骨干。另外,您将自己暴露在拼写错误的类型中,而没有真正简单的方法来检测它(因为这一切都是通过字符串比较完成的。)使用 instanceof 允许 JavaScript 编译器(如 node.js)检测任何拼写错误,并且编译失败应该反对在 Backbone 的更新版本中更改名称,使重大更改更容易识别。
          猜你喜欢
          • 2012-06-04
          • 1970-01-01
          • 2017-02-12
          • 2014-05-12
          • 2012-05-11
          • 2012-03-12
          相关资源
          最近更新 更多