问题
I'm having a problem with Typescript and Backbone collections. Here's some groundwork:
class BaseChartModel extends Backbone.Model { }
class ScatterPlotModel extends BaseChartModel { }
class BarChartModel extends BaseChartModel { }
class MixedChartCollection extends Backbone.Collection { public model: BaseChartModel; ... }
class ScatterPlotCollection extends Backbone.Collection { public model: ScatterPlotModel; ... }
class BarChartCollection extends Backbone.Collection { public model: BarChartModel; ... }
Then I do the following:
var scatterPlotCollection = new ScatterPlotCollection();
var scatterPlotCollectionXhr = scatterPlotCollection.fetch({...});
var barChartCollection = new BarChartCollection();
var barChartCollectionXhr = barChartCollection.fetch({...});
$.when(scatterPlotCollectionXhr, barChartCollectionXhr).done(() => {
mixedCollection = new MixedChartCollection();
mixedCollection.add(scatterPlotCollection.models, { silent: true });
mixedCollection.add(barChartCollection.models, { silent: true });
chartViewList = new MixedChartViewList({ collection: mixedCollection });
chartViewList.render();
});
Inside render():
public render(){
var self = this;
this.$el.html(this.template({}));
this.collection.forEach(
(chartModel: BaseChartModel) => {
this.$el.append(self.AddChartView(chartModel).render());
}
);
return this;
}
public AddChartView(baseChartModel: BaseChartModel) : BaseChartView {
var newChartView: BaseChartView;
if(baseChartModel instanceof ScatterPlotModel){
newChartView = new ScatterPlotView({ model: baseChartModel});
} else if (baseChartModel instanceof BarChartModel){
newChartView = new BarChartView({ model: baseChartModel});
}
....
}
Except instanceof
never evaluates to true because it seems that the 'class type' deriving from Backbone.Model
gets assigned to Backbone.Model.attributes
rather than being an instance of the class itself. I believe this is because when implementing my classes that derive from Backbone.Model I followed this approach and it seems like it may be the reason for this problem. Basically it delegates get/set properties on the TS class to the underlying Backbone.model.get()/set() which in turn sets the values on the attributes
property.
It seems I have to either drop this approach (and hope that was the problem) or figure out a way to do a loosely coupled type check similar to or using instanceof
between the baseChartModel.attributes
object and my class prototype for App.BackBone.Models.ScatterPlotModel
This breakpoint is at the line with instanceof
comparison

Any ideas?
回答1:
The approach that you are using seems valid enough. I have plugged the following code into the TypeScript playground just to check a few javascript symantics:
class A { }
class B extends A { }
class Checker {
static isA(input: A) {
return (input instanceof A);
}
}
var a = new A();
var b = new B();
document.writeln('a instanceof A ' + (a instanceof A) + '<br/>');
document.writeln('b instanceof B ' + (b instanceof B) + '<br/>');
document.writeln('b instanceof A ' + (b instanceof A) + '<br/>');
document.writeln('b instanceof A (via function) ' + Checker.isA(b) + '<br/>');
var aArray : A[] = [];
aArray.push(a);
aArray.push(b);
for(var i = 0; i < aArray.length; i++) {
document.writeln('aArray[' + i + '] instance of A ' + (aArray[i] instanceof A) + '<br/>' );
}
This gives the following output:
a instanceof A true
b instanceof B true
b instanceof A true
b instanceof A checker true
aArray[0] instance of A true
aArray[1] instance of A true
This must mean that the call
mixedCollection.add( scatterPlotCollection.models, { silent: true });
is causing the problem here.
Possibly scatterPlotCollection.models is NOT returning your original objects ( i.e. ScatterPlotModel or BarChartModel ), and is instead just returning [Object object], hence the instance of is failing ?
Hope this helps,
回答2:
I guess I know where a 'bug': somehow declaration
public model: CustomModelType
doesn't work;
But, if you will create a collection like this:
new MyCustomCollection(null, { model: CustomModelType });
Then backbone will be able to create a models as expected.
Why it happens, I don't know :( May be a bug in type definition.
来源:https://stackoverflow.com/questions/15728582/typescript-type-checking-backbone-model-instance-cannot-be-type-checked