ZK 如何使用所选项目更新 ListBox ListModel

ZK How to update ListBox ListModel using selected item

我正在使用 ZK 组件制作 Web 文件浏览器并找到一个块。有什么方法可以使用列表框的选定项更新 ListBox 模型? 用例是在遍历文件和文件夹时,用户单击文件夹,列表将刷新为所选文件夹的内容。选择事件被触发,对于常规文件,它处理得很好,但文件夹不是。

我的代码: myfilesvm.zul

<zk>
    <window apply="org.zkoss.bind.BindComposer"
        viewModel="@id('vm') @init('com.my.zk.mvvm.MyFilesViewModel')">
        <hlayout>
            <listbox vflex="true" hflex="1" model="@load(vm.files)"
                id="fileBrowser" selectedItem="@bind(vm.selectedFile)">
                <auxhead>
                    <auxheader colspan="3">File List</auxheader>
                    <auxheader colspan="3">
                        <hlayout>
                            <!-- breadcrumb, implemented later -->
                        </hlayout>
                    </auxheader>
                </auxhead>
                <listhead>
                    <listheader label="Name" />
                    <listheader label="Size" />
                    <listheader label="Modified" />
                </listhead>
                <template name="model" var="file">
                    <listitem>
                        <listcell label="@load(file.name)" />
                        <listcell label="@load(file.length())" />
                        <listcell label="@load(file.lastModified())" />
                    </listitem>
                </template>
            </listbox>
        </hlayout>
        <separator />
    </window>
</zk>

MyFilesViewModel.java

package com.my.zk.mvvm;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Arrays;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.zkoss.bind.annotation.Init;
import org.zkoss.bind.annotation.NotifyChange;
import org.zkoss.zul.Filedownload;
import org.zkoss.zul.ListModel;
import org.zkoss.zul.ListModelList;

import com.my.zk.FileCrumbManager;

public class MyFilesViewModel  {



    private static Logger log = LoggerFactory.getLogger(MyFilesViewModel.class);
//  AuthenticationService authService = new AuthenticationServiceImpl();
//  UserCredential cre = authService.getUserCredential();
    String homeFolder = "D:\path\home";

    ListModel<File> files = new ListModelList<File>(Arrays.asList(FileCrumbManager.populateList(new File(homeFolder))));
    File selectedFile;

    @Init
    public void init() { // Initialize

    }

    public ListModel<File> getFiles() {
        return files;
    }

    @NotifyChange({ "selectedFile" })
    public void setFiles(ListModel<File> files) {
        this.files = files;
    }

    public File getSelectedFile() {
        return selectedFile;
    }

    public void pilihFile() {
        if (getSelectedFile().isDirectory()) {
            log.info("File is a directory");
            this.files = new ListModelList<File>(
                    Arrays.asList(FileCrumbManager.populateList(new File(getSelectedFile().getAbsolutePath()))));
        } else {
            try {
                Filedownload.save(getSelectedFile(), null);
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                log.error(e.getMessage());
            }
        }
    }

    public void setSelectedFile(File selectedFile) {
        this.selectedFile = selectedFile;
        pilihFile();
    }

}

感谢您的帮助。谢谢。

pilihFile()中刷新ListModelList的正确方法是:

this.files.clear();
this.files.addAll(Arrays.asList(FileCrumbManager.populateList(new File(getSelectedFile().getAbsolutePath()))));

因为Listbox是模型驱动渲染,所以应该通过操作模型对象来控制渲染。当您调用 ListModelList 的方法时,它会通知 Listbox 呈现到浏览器中。如果把this.files换成新的对象,ZK就不知道了。这就是您的浏览器没有更新的原因。