0

MVVM Listbox Load Huge Amount of data page by page

asked 2013-06-11 07:48:48 +0800

Senthilchettyin gravatar image Senthilchettyin flag of India
2615 3 8
http://emrpms.blogspot.in...

Hi

Is any example available on the above subject in ZK CE version ?

I found this and this

But that is not in MVVM. Can we achieve the same in MVVM

delete flag offensive retag edit

Comments

I found two different way of implementation here and here.

But i am not sure which is best. Any help ?

Senthilchettyin ( 2013-06-11 10:23:50 +0800 )edit

I suggest the official one

benbai ( 2013-06-17 10:23:49 +0800 )edit

6 Answers

Sort by ยป oldest newest most voted
0

answered 2013-06-13 16:06:23 +0800

Senthilchettyin gravatar image Senthilchettyin flag of India
2615 3 8
http://emrpms.blogspot.in...

Any help please.............................

link publish delete flag offensive edit
0

answered 2013-10-07 15:23:07 +0800

Senthilchettyin gravatar image Senthilchettyin flag of India
2615 3 8
http://emrpms.blogspot.in...

Why there is no example on MVVM on this subject ?

link publish delete flag offensive edit

Comments

Because no one wrote a smalltalk on this with MVVM? But I think the document cover this issue: http://books.zkoss.org/wiki/ZKDeveloper'sReference/MVVM/Advanced/DisplayingHugeAmountofData

benbai ( 2013-10-08 08:35:08 +0800 )edit
0

answered 2013-10-08 13:51:42 +0800

Senthilchettyin gravatar image Senthilchettyin flag of India
2615 3 8
http://emrpms.blogspot.in...

No, actually here is the really good one

http://fadishei.wordpress.com/2012/03/22/zk-mvvm-design-pattern-and-server-side-paging/

But i do not understand the last statement "Alternatively, you could handle onPaging event of the paging component instead of binding its activePage to the ViewModel. But I think this would be a little messier!"

@Ben

If you have time, you can convert the below demo like the above one using Paging component

http://www.zkoss.org/zkdemo/listbox/paging

link publish delete flag offensive edit

Comments

I think you can just apply the one you suggested? Or are there still any missing parts?

benbai ( 2013-10-09 23:26:09 +0800 )edit

In my example I use the paging component http://www.learntechnology.net/2012/11/13/zklargeresults.html I'll have to try the approach just using active page and see how it works out. Does seem slightly cleaner.

rickcr ( 2013-10-10 13:57:42 +0800 )edit

Note, I updated my example to use activePage as well (vs the onPaging event) http://www.learntechnology.net/2012/11/13/zklargeresults.html

rickcr ( 2013-10-10 14:39:48 +0800 )edit
0

answered 2013-10-11 09:02:30 +0800

benbai gravatar image benbai
2228 6
http://www.zkoss.org

I've done ROD with ZK CE without paging:

test.zul

<zk xmlns:w="client">
    <style>
        .first,
        .last {
            background: none !important;
        }
        .first .z-listcell-cnt,
        .last .z-listcell-cnt {
            height: 0px;
        }
        .first .z-listcell,
        .last .z-listcell {
            border: 0;
            padding: 0 !important;
        }
    </style>
    <window apply="org.zkoss.bind.BindComposer"
        viewModel="@id('vm') @init('test.TestVM')">
        <listbox width="350px" height="200px"
            onRefreshModel="@command('refreshModel')"
            model="@load(vm.model) @template(forEachStatus.index eq vm.first ? 'model1' : forEachStatus.index eq vm.last ? 'model2' : 'model')">
            <attribute w:name="_onScrollPos"><![CDATA[
                function () {
                    this.$_onScrollPos();
                    if (!this._rodIng) {
                        var wgt = this;
                        // clear old timer
                        if (this._rodTimer)
                            clearTimeout(this._rodTimer);
                        // add a delay to make it more smooth
                        this._rodTimer = setTimeout(function () {
                            wgt._rodIng = true;
                            var body = wgt.$n('body');
                            wgt._topToRestore = body.scrollTop;
                            wgt.fire('onRefreshModel', {
                                top: body.scrollTop
                            }, {toServer: true});
                            this._rodTimer = null;
                        }, 500);
                    }
                }
            ]]></attribute>
            <attribute w:name="setModel"><![CDATA[
                function (v) {
                    this.$setModel(v);
                    if (this._rodIng) {
                        var wgt = this;
                        setTimeout(function () {
                            wgt.$n('body').scrollTop = wgt._topToRestore;
                        }, 50);
                        setTimeout(function () {
                            wgt._rodIng = null;
                        }, 150);
                    }
                }
            ]]></attribute>
            <template name="model1" var="item">
                <listitem sclass="first" height="@load(vm.topStyle)">
                    <listcell label="@load(item)" />
                </listitem>
            </template>
            <template name="model" var="item">
                <listitem>
                    <listcell label="@load(item)" />
                </listitem>
            </template>
            <template name="model2" var="item">
                <listitem sclass="last" height="@load(vm.bottomStyle)">
                    <listcell label="@load(item)" />
                </listitem>
            </template>
        </listbox>
    </window>
</zk>

TestVM.java

package test;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.zkoss.bind.annotation.Command;
import org.zkoss.bind.annotation.ContextParam;
import org.zkoss.bind.annotation.ContextType;
import org.zkoss.bind.annotation.NotifyChange;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zul.ListModel;
import org.zkoss.zul.ListModelList;

/**
 * tested with ZK 6.5.3
 * 
 * @author benbai
 *
 */
@SuppressWarnings({ "rawtypes", "unchecked" })
public class TestVM {
    private ListModelList _model = null;
    private int _start = 1;
    /** At most 48 items or will hits ZK built-in optimization
     * and break this mechanism
     * 
     */
    private int _viewSize = 48;
    private int _total = 1000000;
    public ListModel getModel () {
        if (_model == null) {
            updateModel();
        }
        return _model;
    }
    public int getFirst () {
        return 0;
    }
    public int getLast () {
        return _viewSize+1;
    }
    public String getTopStyle () {
        return (_start-1)*30 + "px";
    }
    public String getBottomStyle () {
        return (_total - _start - _viewSize + 1)*30 + "px";
    }
    @Command
    @NotifyChange({"model", "topStyle", "bottomStyle"})
    public void refreshModel (@ContextParam(ContextType.TRIGGER_EVENT) Event event) {
        int top = (Integer)((Map)event.getData()).get("top");
        if (top < ((_start-1) * 30)
            || top > ((_start+_viewSize-3) * 30)) {
            _start = top/30 - 25;
            if (_start < 1) {
                _start = 1;
            } else if (_start + _viewSize > _total) {
                _start = _total - _viewSize + 1;
            }
            updateModel();
        }
    }
    private void updateModel () {
        // assume get data with start/end index from db here
        List l = null;
        l = new ArrayList();
        l.add(""); // fake item to build scroll
        for (int i = _start; i <= (_start + _viewSize - 1); i++) {
            l.add("Item " + i);
        }
        l.add(""); // fake item to build scroll
        _model = new ListModelList(l);
    }
}
link publish delete flag offensive edit
0

answered 2013-10-11 09:06:49 +0800

benbai gravatar image benbai
2228 6
http://www.zkoss.org

I've done ROD with ZK CE without paging:

test.zul

<zk xmlns:w="client">
    <style>
        .first,
        .last {
            background: none !important;
        }
        .first .z-listcell-cnt,
        .last .z-listcell-cnt {
            height: 0px;
        }
        .first .z-listcell,
        .last .z-listcell {
            border: 0;
            padding: 0 !important;
        }
    </style>
    <window apply="org.zkoss.bind.BindComposer"
        viewModel="@id('vm') @init('test.TestVM')">
        <listbox width="350px" height="200px"
            onRefreshModel="@command('refreshModel')"
            model="@load(vm.model) @template(forEachStatus.index eq vm.first ? 'model1' : forEachStatus.index eq vm.last ? 'model2' : 'model')">
            <attribute w:name="_onScrollPos"><![CDATA[
                function () {
                    this.$_onScrollPos();
                    if (!this._rodIng) {
                        var wgt = this;
                        // clear old timer
                        if (this._rodTimer)
                            clearTimeout(this._rodTimer);
                        // add a delay to make it more smooth
                        this._rodTimer = setTimeout(function () {
                            wgt._rodIng = true;
                            var body = wgt.$n('body');
                            wgt._topToRestore = body.scrollTop;
                            wgt.fire('onRefreshModel', {
                                top: body.scrollTop
                            }, {toServer: true});
                            this._rodTimer = null;
                        }, 500);
                    }
                }
            ]]></attribute>
            <attribute w:name="setModel"><![CDATA[
                function (v) {
                    this.$setModel(v);
                    if (this._rodIng) {
                        var wgt = this;
                        setTimeout(function () {
                            wgt.$n('body').scrollTop = wgt._topToRestore;
                        }, 50);
                        setTimeout(function () {
                            wgt._rodIng = null;
                        }, 150);
                    }
                }
            ]]></attribute>
            <template name="model1" var="item">
                <listitem sclass="first" height="@load(vm.topStyle)">
                    <listcell label="@load(item)" />
                </listitem>
            </template>
            <template name="model" var="item">
                <listitem>
                    <listcell label="@load(item)" />
                </listitem>
            </template>
            <template name="model2" var="item">
                <listitem sclass="last" height="@load(vm.bottomStyle)">
                    <listcell label="@load(item)" />
                </listitem>
            </template>
        </listbox>
    </window>
</zk>

TestVM.java

package test;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.zkoss.bind.annotation.Command;
import org.zkoss.bind.annotation.ContextParam;
import org.zkoss.bind.annotation.ContextType;
import org.zkoss.bind.annotation.NotifyChange;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zul.ListModel;
import org.zkoss.zul.ListModelList;

/**
 * tested with ZK 6.5.3
 * 
 * @author benbai
 *
 */
@SuppressWarnings({ "rawtypes", "unchecked" })
public class TestVM {
    private ListModelList _model = null;
    private int _start = 1;
    /** At most 48 items or will hits ZK built-in optimization
     * and break this mechanism
     * 
     */
    private int _viewSize = 48;
    private int _total = 1000000;
    public ListModel getModel () {
        if (_model == null) {
            updateModel();
        }
        return _model;
    }
    public int getFirst () {
        return 0;
    }
    public int getLast () {
        return _viewSize+1;
    }
    public String getTopStyle () {
        return (_start-1)*30 + "px";
    }
    public String getBottomStyle () {
        return (_total - _start - _viewSize + 1)*30 + "px";
    }
    @Command
    @NotifyChange({"model", "topStyle", "bottomStyle"})
    public void refreshModel (@ContextParam(ContextType.TRIGGER_EVENT) Event event) {
        int top = (Integer)((Map)event.getData()).get("top");
        if (top < ((_start-1) * 30)
            || top > ((_start+_viewSize-3) * 30)) {
            _start = top/30 - 25;
            if (_start < 1) {
                _start = 1;
            } else if (_start + _viewSize > _total) {
                _start = _total - _viewSize + 1;
            }
            updateModel();
        }
    }
    private void updateModel () {
        // assume get data with start/end index from db here
        List l = null;
        l = new ArrayList();
        l.add(""); // fake item to build scroll
        for (int i = _start; i <= (_start + _viewSize - 1); i++) {
            l.add("Item " + i);
        }
        l.add(""); // fake item to build scroll
        _model = new ListModelList(l);
    }
}
link publish delete flag offensive edit
0

answered 2013-10-14 02:33:27 +0800

benbai gravatar image benbai
2228 6
http://www.zkoss.org

Another implementation with Paging and MVVM

test.zul

<zk>
    <window apply="org.zkoss.bind.BindComposer"
        viewModel="@id('vm') @init('test.TestVM')">
        <div width="350px">
            <listbox model="@load(vm.model)" height="350px" width="350px"
                style="border-bottom: 0;">
                <template name="model" var="item">
                    <listitem>
                        <listcell label="@load(item)" />
                    </listitem>
                </template>
            </listbox>
            <paging width="350px" totalSize="@load(vm.totalSize)" pageSize="@load(vm.pageSize)"
                activePage="@bind(vm.activePage)" onPaging="@command('refreshModel')"
                style="padding-left: 0; padding-right: 0; border-left: 1px solid #cfcfcf; border-right: 1px solid #cfcfcf;" />
        </div>
    </window>
</zk>

TestVM.java

package test;

import java.util.ArrayList;
import java.util.List;
import org.zkoss.bind.annotation.Command;
import org.zkoss.bind.annotation.NotifyChange;
import org.zkoss.zul.ListModel;
import org.zkoss.zul.ListModelList;

/**
 * tested with ZK 6.5.3
 * 
 * @author benbai
 *
 */
@SuppressWarnings({ "rawtypes", "unchecked" })
public class TestVM {
    private int _active = 0;

    private int _viewSize = 100;
    private int _total = 1000000;
    // assume get data by start/end index
    public ListModel getModel () {
        List l = new ArrayList();
        int start = _active * _viewSize + 1;
        int end = Math.min((_active + 1) * _viewSize, _total);
        for (int i = start; i <= end; i++) {
            l.add("Item " + i);
        }
        return new ListModelList(l);
    }
    // getters, setter
    public int getTotalSize () {
        return _total;
    }
    public int getPageSize() {
        return _viewSize;
    }
    public int getActivePage () {
        return _active;
    }
    public void setActivePage (int active) {
        _active = active;
    }
    @Command
    @NotifyChange("model")
    public void refreshModel () {
        // empty function for command to trigger NotifyChange
    }
}
link publish delete flag offensive edit
Your answer
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!

[hide preview]

Question tools

Follow
1 follower

RSS

Stats

Asked: 2013-06-11 07:48:48 +0800

Seen: 88 times

Last updated: Oct 14 '13

Support Options
  • Email Support
  • Training
  • Consulting
  • Outsourcing
Learn More