I've subclassed Array (using TypeScript), in order to be able to add extra functions to the Array. See code below.
Since then, I've noticed that the {for}
tag of JsRender/JsViews does not work any more.
I've also noticed JsRender/JsViews uses $.isArray(...)
in order to iterate arrays, which will return false
on subclassed arrays.
When I change JsRender/JsViews code to use (data instanceof Array)
it does work.
Is there another way (without changing JsRender/JsViews code) to get subclassed arrays to work with JsRender/JsViews {for}
tag?
Typescript:
module MyModule {
export class Collection<T> implements Array<T> {
constructor() {
Array.apply(this, arguments);
return new Array();
}
length: number;
toString(): string { return ""; }
//... All other Array properties/methods
}
// replace dummy declarations with the real thing
Collection['prototype'] = new Array();
}
Generated Javascript:
var MyModule;
(function (MyModule) {
var Collection = (function () {
function Collection() {
Array.apply(this, arguments);
return new Array();
}
Collection.prototype.toString = function () { return ""; };
//... All other Array properties/methods
return Collection;
})();
MyModule.Collection = Collection;
// replace dummy declarations with the real thing
Collection['prototype'] = new Array();
})(MyModule|| (MyModule= {}));
Your SubclassedCollection is not a JavaScript array (just as a jQuery object is not a JavaScript array). Unlike your Collection, it returns "[object Object]"
from Object.prototype.toString.call(ob)
- rather than "[object Array]"
.
One possible approach might be to use the function:
function toArray(ob) {
return Array.prototype.slice.call(ob);
}
and either write
MyModule.ViewModel = { Coll: toArray(collection2) };
or else register toArray
as a helper (~toArray
) or a converter ("toArray"
) and then write your template as:
{{for ~toArray(Coll)}}
(or alternatively {{for Coll convert=~toArray}}
or {{for Coll convert="toArray"}}
).
Here is an updated fork of your jsfiddle: http://jsfiddle.net/16L670re/