jasonkneen / UTiL

Collection of utility scripts for Titanium (Alloy).
221 stars 88 forks source link

Ui.js use in a ListView ( multiple instances ) #16

Closed masterbee closed 10 years ago

masterbee commented 10 years ago

@FokkeZB , thank you again for the prior code update to handle remote images, this module is great and I use it frequently. That said I have hit a bit of a snag in terms of multiple instances of this in a list view.

In short, I am using a list view and an itemTemplate where I have 4 of these <View module="ui"... setup in a grid. Each with it's own unique bindId. In the creation of the list view I am setting the correct properties.

The behaviour I am getting is a bit odd. In short the first of the 4 views works as it should, but the other 3 are blank. When I the code of the other 3 to <ImageView ... everything works so I can rule out any view positioning issues.

I am thinking that there is some mechanic of ListvView and instance of Ui.js that is only allowing one of the 4 Views to work correctly.

Thoughts? and many thanks.

@masterbee

FokkeZB commented 10 years ago

Do you have a full code example?

masterbee commented 10 years ago

@FokkeZB, I put ui.js in app/lib so that I can use the module attribute and below is the code that I used to test it out. As you will see, there are no images being loaded in the views. The expected behaviour is that you will see a list of 4 images side by side in each list item ( 2 at the moment are coded ). It is interesting to note, that if you change the views to ImageViews, run the app once so get the correct effect, and then change them back, it works. This is probably because the images are already cached internally by the device.

Here is the code:

<Alloy>
    <Window backgroundColor="white">
        <ListView id="listView" defaultItemTemplate="template">

            <!-- The Templates tag sets the ListView's templates property -->

            <Templates>

                <!-- Define your item templates within the Templates tags or use the
                     Require tag to include a view that only contains an ItemTemplate -->

                <ItemTemplate name="template">
                    <View layout="horizontal" width="Ti.UI.FILL" hieght="Ti.UI.SIZE">
                        <View width="24%" left="1%" layout="vertical" top="0" hieght="Ti.UI.SIZE">
                            <View module="ui" bindId="photoone" width="Ti.UI.FILL" hieght="Ti.UI.FILL" backgroundSize="cover" />
                            <Label bindId="es_info" id="title" />
                        </View>
                        <View width="24%" left="1%" layout="vertical" top="0" hieght="Ti.UI.FILL">
                            <View module="ui" bindId="phototwo" width="Ti.UI.FILL" hieght="Ti.UI.FILL" backgroundSize="cover" /> 
                            <Label bindId="es_info" id="title" />
                        </View>
                        <View width="24%"  layout="vertical" top="0" hieght="Ti.UI.FILL">
                            <View module="ui" bindId="photothree" width="Ti.UI.FILL" hieght="Ti.UI.FILL" backgroundSize="cover" />
                            <Label bindId="es_info" id="title" />
                        </View>
                        <View width="24%" left="1%" layout="vertical" top="0" hieght="Ti.UI.FILL">
                            <View module="ui" bindId="photofour" width="Ti.UI.FILL" hieght="Ti.UI.FILL" backgroundSize="cover" />
                            <Label bindId="es_info" id="title" />
                        </View>
                    </View>
                </ItemTemplate>
            </Templates>

            <ListSection>
                <ListItem 
                    photoone:backgroundImage="http://newevolutiondesigns.com/images/freebies/colorful-background-1.jpg" es_info:text="Image 1" 
                    phototwo:backgroundImage="http://newevolutiondesigns.com/images/freebies/colorful-background-2.jpg" es_info:text="Image 2" 
                    photothree:backgroundImage="http://newevolutiondesigns.com/images/freebies/colorful-background-3.jpg" es_info:text="Image 3"
                    photofour:backgroundImage="http://newevolutiondesigns.com/images/freebies/colorful-background-4.jpg" es_info:text="Image 4" 
                    />

                 <ListItem
                    photoone:backgroundImage="http://newevolutiondesigns.com/images/freebies/colorful-background-3.jpg" es_info:text="Image 3" 
                    phototwo:backgroundImage="http://newevolutiondesigns.com/images/freebies/colorful-background-1.jpg" es_info:text="Image 1" 
                    photothree:backgroundImage="http://newevolutiondesigns.com/images/freebies/colorful-background-4.jpg" es_info:text="Image 4"
                    photofour:backgroundImage="http://newevolutiondesigns.com/images/freebies/colorful-background-2.jpg" es_info:text="Image 2" 
                    />

            </ListSection>
        </ListView>
    </Window>
</Alloy>
FokkeZB commented 10 years ago

If you take a look at the compiled source for this you'll see that you can't use a the module attribute in a ListView template. It will just result in a regular view having a module property:

            var __alloyId8 = {
                type: "Ti.UI.View",
                childTemplates: function() {
                    var __alloyId9 = [];
                    var __alloyId11 = {
                        type: "Ti.UI.View",
                        bindId: "photoone",
                        properties: {
                            module: "ui",
                            bindId: "photoone",
                            width: Ti.UI.FILL,
                            hieght: Ti.UI.FILL,
                            backgroundSize: "cover"
                        }
                    };
                    __alloyId9.push(__alloyId11);
                    var __alloyId12 = {
                        type: "Ti.UI.Label",
                        bindId: "es_info",
                        properties: {
                            width: Ti.UI.SIZE,
                            height: Ti.UI.SIZE,
                            color: "#000",
                            bindId: "es_info"
                        }
                    };
                    __alloyId9.push(__alloyId12);
                    return __alloyId9;
                }(),
                properties: {
                    width: "24%",
                    left: "1%",
                    layout: "vertical",
                    top: "0",
                    hieght: Ti.UI.SIZE
                }
            };
masterbee commented 10 years ago

@FokkeZB , fair point, so my next question would be to ask how can we make this happen by Alloy alone in a ListView? Is it even possible?

Many thanks again.

FokkeZB commented 10 years ago

Not as a generic solution, only by fetching/caching the images and then resetting the list view items with the right image src.

masterbee commented 10 years ago

@FokkeZB , thanks I had a hunch it would go that route. Since you have already patched it to allow for remote URL's and are already triggering on PostLayout, any thought to make this work. In short it appears to have all the mechanics, it is more the timing that is my read of the issue.

Make sense?

FokkeZB commented 10 years ago

Like I said, what you want can not be done wrapped in a generic module. You will have to write specific code around your ListView, that will use similar logic as UI.js to check if a cached version is available, if not download, and then re-set the list item's image property.