基础构造函数中的这个上下文是模块本身 - Typescript

时间:2013-03-30 11:18:38

标签: backbone.js typescript

注意:更改标题后回答以获得更好的可搜索性,因为这与骨干无关。

 module App.BackBone.Collections {  
     export class MixedChartCollection extends Backbone.Collection {        
            public model: App.BackBone.Models.BaseChartModel;        
            constructor(models?: any, options?: any) {
                  super(models, options);
            }
       }
}

似乎调用了基础Backbone.Collection构造函数,this上下文是我的模块,而不是我的类o_O

这是来自backbone.js的构造函数:

 var Collection = Backbone.Collection = function (models, options) {
      options || (options = {});
      if (options.url) this.url = options.url;
      if (options.model) this.model = options.model;
      if (options.comparator !== void 0) this.comparator = options.comparator;
      this._reset();  //ERROR: this._reset is not a function
      this.initialize.apply(this, arguments);
      if (models) this.reset(models, _.extend({ silent: true }, options));
  }; 

在图像中,您可以看到App.BackBone.Collections如何具有相同的3个成员(红色,其中一个是所讨论的类)作为this上下文,this._reset最终未定义因为我们真正希望它“包裹”我的某个对象而不是

为什么要这样做?

以下是此类的已编译代码:

var App;
(function (App) {
    (function (BackBone) {
        (function (Collections) {
            var MixedChartCollection = (function (_super) {
                __extends(MixedChartCollection, _super);
                function MixedChartCollection(models, options) {
                    _super.call(this, models, options); //HERE "this" is not MixedChartCollection instance 
                }
                return MixedChartCollection;
            })(Backbone.Collection);
            Collections.MixedChartCollection = MixedChartCollection;            
        })(BackBone.Collections || (BackBone.Collections = {}));
        var Collections = BackBone.Collections;
    })(App.BackBone || (App.BackBone = {}));
    var BackBone = App.BackBone;
})(App || (App = {}));          

enter image description here

2 个答案:

答案 0 :(得分:2)

我假设你有一个像这样声明的BaseChartModel:

module App.Backbone.Models {
    export class BaseChartModel extends Backbone.Model {

    }
}

你的MixedChartCollection:

module App.Backbone.Collections {
    export class MixedChartCollection extends Backbone.Collection {
        public model: App.Backbone.Models.BaseChartModel;
        constructor(models?: any, options?: any) {
            super(models, options);
        }
    }
}

我看到的一个关键问题是您拥有包含BackboneBackbone的命名空间。这些转换为JavaScript:

var App;
(function (App) {
    (function (Backbone) {
        (function (Models) {
            var BaseChartModel = (function (_super) {
                __extends(BaseChartModel, _super);
                function BaseChartModel() {
                    _super.apply(this, arguments);

                }
                return BaseChartModel;
            })(Backbone.Model);
            Models.BaseChartModel = BaseChartModel;            
        })(Backbone.Models || (Backbone.Models = {}));
        var Models = Backbone.Models;
    })(App.Backbone || (App.Backbone = {}));
    var Backbone = App.Backbone; // << scope chain now includes Backbone
})(App || (App = {}));
var App;
(function (App) {
    (function (Backbone) {
        (function (Collections) {
            var MixedChartCollection = (function (_super) {
                __extends(MixedChartCollection, _super);
                function MixedChartCollection(models, options) {
                    _super.call(this, models, options);
                }
                return MixedChartCollection;
            })(App.Backbone.Collection);
            Collections.MixedChartCollection = MixedChartCollection;            
        })(Backbone.Collections || (Backbone.Collections = {}));
        var Collections = Backbone.Collections;
    })(App.Backbone || (App.Backbone = {}));
    var Backbone = App.Backbone;  // << scope chain now includes Backbone
})(App || (App = {}));

您会发现最终导致Backbone设置为App.Backbone的冲突(生成代码的最后一行)。

var Backbone = App.Backbone; // << scope chain now includes Backbone

这完全改变了代码的性质,因为现在对于本地范围的Backbone实例值而不是BackboneJS Model类发生了继承(对于Collection类也是如此)

尝试更改模块声明,以便不为集合和模型类使用Backbone命名空间。

module App.My.Models {
    export class BaseChartModel extends Backbone.Model {

    }
}

module App.My.Collections {
    export class MixedChartCollection extends Backbone.Collection {
        public model: App.My.Models.BaseChartModel;
        constructor(models?: any, options?: any) {
            super(models, options);
        }
    }
}

答案 1 :(得分:2)

好的想出来了。

它与我实例化类的方式有关:

 var mixedCollection: App.BackBone.Collections.MixedChartCollection
                        = App.BackBone.Collections.MixedChartCollection();

注意到我遗漏了导致我出问题的“新”关键字。

为什么编译器没有抓住这个?我不知道。没有必要,但如果有人想回答背后的推理,那将标记为答案。