royale-asjs icon indicating copy to clipboard operation
royale-asjs copied to clipboard

ICollectionView doesn't support indexed array syntax ([]) in JS

Open estanglerbm opened this issue 5 years ago • 5 comments

Both SWF and JS allow indexed array syntax for XMLListCollection. For example, mycol[0].

SWF supports indexed array syntax for ICollectionView, but JS does not; it shows undefined.

See attached test case.

TestCollectionBrackets.mxml.txt

estanglerbm avatar Dec 02 '20 15:12 estanglerbm

That was a decision we made to keep the JS as performant as possible.

Harbs avatar Dec 02 '20 18:12 Harbs

Actually @Harbs , I already added support for this type of thing to the compiler. We already have this working with BinaryData and org.apache.royale.collections.IArrayList

@estanglerbm I don't have time to check now, but you could try adding: [RoyaleArrayLike(getValue="getItemAt",setValue="setItemAt",setterArgSequence="value,index",length="length",lengthAccess="getter")] To the top of ListCollectionView and then rebuilding MXRoyale swc.

This enhances the for each loops and also recognises numeric array index access and assignment, and generates the getItemAt/setItemAt code for that, with no actual runtime overhead. But only if the compiler knows it is of the correct type.

I would prefer to test that myself before recommending it but I don't have time right now, sorry. If it doesn't work, I can look into it this coming weekend

greg-dove avatar Dec 02 '20 19:12 greg-dove

@greg-dove That's great about additional compiler support, but I don't understand.

ListCollectionView (and thus XMLListCollection) already supports indexed array syntax, through getProperty() / proxy_getProperty(). How would RoyaleArrayLike on ListCollectionView help ICollectionView get the syntax? (That is, in the test case without RoyaleArrayLike, using the syntax directly on an XMLListCollection works, but using an ICollectionView of that same object only works in SWF, not JS, as I mentioned.)

Also, what happens if I used indexed array syntax on an ICollectionView that is not a ListCollectionView, with this possible workaround? I assume the same as what would happen now in SWF without the possible workaround.

estanglerbm avatar Dec 02 '20 22:12 estanglerbm

In Flash, when it is time to execute obj[prop], the runtime figures out the type of the object and makes the correct access (for XML, call the .property() or .attribute(), for Proxy, call getProperty() or callProperty()).

There is no such support in Royale for JS targets. Royale could have output some general property access code but that would slow everything down, so for now (and maybe forever) folks have to strongly-type access to types that require special access.

So, if you have an ICollectionView, you could test if it is a ListCollectionView and then cast/coerce it and then the compiler should generate the getProperty

var myICollectionView:ICollectionView;
if (myICollectionView is ListCollectionView) 
{
    var myListCollectionView = myICollectionView as ListCollectionView;
    trace(myListCollectionView[0]);
}

RoyaleArrayLike lets you do that for the more general case where things are not Proxy or XML, but as you say, if you are not sure of the concrete type you might get an error and probably should do a type-check anyway.

aharui avatar Dec 03 '20 00:12 aharui

@aharui Yeah, that's what I did for a workaround (I know they are most likely ListCollectionView).

estanglerbm avatar Dec 03 '20 02:12 estanglerbm