Tips for using lazy & resize replication in OpenLaszlo

Here’s the scenario: I want to display 500 items in a scrolling list, but using regular replication causes 500 views to become instantiated, which can take a loooong time. Lazy & resize replication helps out by only instantiating the views that the users can see. Lazy replication then manages copying the relevant data to views that scroll into the clipped area. The dev guide explains the purpose quite well:

“The lazy replication manager creates only enough replicated views necessary to display the data, so there is not a view for each data node. This enables the display of very large datasets.”

This is great because instantiating views is expensive, and we don’t want to make any more of them than we need to. This efficiency gain comes with a price of added complexity however. Here are some tips to hopefully make your experience with lazy & resize replication a little less painful:

  • $path references don’t reliably update in lazily replicated views. Don’t waste your time using them. Use applyData() instead (more on applyData below)
  • Make sure all visual elements that might change in your replicated view are based on the data. Instead of using attributes in the view to keep track of visual information, use attributes in the dataset instead (eg this.datapath.setNodeAttribue(‘someKey’,’someValue’). You’ll probably want to use applyData() as a hook into making visual adjustments as needed.
  • applyData() is called in a replicated view whenever the data in that view changes. With lazily replicated views, applyData() is called on replicated views as the user scrolls so that data can be copied into the new LzView that just scrolled into the clipped area. Make sure that the datapath specified on the replicated view points to data that will definitely be there…. otherwise applyData() wont get fired.
  • As a workaround to the $path problem, grab any data that you need from the dataset when applyData() is fired. (e.g. this.datapath.getNodeAttribute(‘somedata’))
  • Make sure to use the dataselectionmanager if you want the user to be able to select more than a single replicated item at a time.
  • A replication manager only gets created if the datapath matches multiple nodes the first time. If there is any chance at all that you’ll match a single node, you should first set the datapath to point to a fake dataset that contains 2 or more nodes to ensure a replication manager will be created. (See the example code below)
  • You can use the fake dataset trick described above to instantiate some views upon applciation startup. This will ensure that a user doesn’t have to wait for those views to be instantiated when the real data comes in.
  • If you updated something in the dataset, and your change isn’t being reflected in the replicated views, you can try calling this.cloneManager.runXPath() from a replicated view as a last resort.

Here’s some example code that covers most of what I’ve talked about above:

<canvas>

    <!-- Let's say this is my real dataset.  It could be
         loaded from the server, but we'll make it local
         for this example -->
    <dataset name="people">
        <people>
            <person name="chrisk" sex="m"/>
            <person name="lyla" sex="f"/>
            <person name="clint" sex="m"/>
            <person name="renais" sex="f"/>
            <person name="ron" sex="m"/>
            <person name="terry" sex="f"/>
            <person name="debi" sex="f"/>
            <person name="luke" sex="m"/>
            <person name="jason" sex="m"/>
            <person name="eileen" sex="f"/>
            <person name="henry" sex="m"/>
            <person name="nik nik" sex="f"/>
            <person name="kel" sex="m"/>
            <person name="hu?" sex="f"/>
        </people>
    </dataset>

    <button text="Replcte views!">
        <method event="onclick">
            replicatedParent.datapath.setXPath('people:/people');
        </method>
    </button>

    <view width="100" height="100" clip="true">
        <!-- use this dataset to ensure a
             replciation manager is created, and also
             create some views on applciation startup
             so that the user doesn't have to
             wait when they request the data  -->
        <dataset name="fakeData">
            <people>
                <person/> <person/> <person/> <person/> <person/> <person/>
            </people>
        </dataset>

        <view id="replicatedParent"
              datapath="local:parent.fakeData:/pepople">
            <text>
                <datapath xpath="person/@name"
                          replication="lazy"/>

                    <!-- Is called when a user scrolls the data into view -->
                    <method name="applyData" args="_d">
                        super.applyData(_d);

                        if( this.datapath.getNodeAttribute('sex') == 'm' ) {
                            this.setBGColor(0xCACAFF);
                        } else {
                            this.setBGColor(0xFFCACA);
                        }
                    </method>
            </text>
        </view>
        <scrollbar/>
    </view>
    <simplelayout axis="y"/>
</canvas>

2 thoughts on “Tips for using lazy & resize replication in OpenLaszlo

  1. Pingback: Alawiki.org » Blog Archive » OpenLaszlo Tips and Tricks

  2. just test you method to large data initializition, and found that _datapath xpath=”person/@name” replication=”lazy”_ is very very useful to optimize, and saw a dramatically render speed, even for hundreds of data items.
    but the method _method name=”applyData” args=”_d”_
    did not see any additional helpness.

Comments are closed.