0

我正在尝试为 CSV 文件创建一个文件上传屏幕,该屏幕将为用户提供上传内容的预览。

我有前端的jsf标签如下:

<p:fileUpload id="selectFile" value="#fileUploadBean.file}" mode="simple"/>
<p:commandButton ajax="false" action="#{fileUploadBean.uploadDataFile}" />
<h:panelGrid id="filePreview" binding="#{fileUploadBean.filePreview}"/>

在后端,我有方法在文件上传时建立预览:

public String uploadDataFile() {
  createFilePreview();
  return "";
}

private void createFilePreview() {
  HtmlPanelGrid dataPrevGrid = new HtmlPanelGrid();
  dataPrevGrid.setColumns(numColumns);
    for (/*loops through all lines in the CSV file*/) {
      String row = it.next(); //get next line in CSV file
      String[] cells = row.split(",");
      for (int i = 0; i < cells.length; i++) {
        String cell = cells[i];
        HtmlOutputText jcell = createHtmlOutputText(cell);
        dataPrevGrid.getChildren().add(jcell);
      }
    }
}

public HtmlPanelGrid getFilePreview() {
    return filePreview;
}

代码全部运行(我在调试时看到它正在运行代码),但是 PanelGrid 组件永远不会随文件预览更新。有趣的是(因为我已将 bean 声明为会话范围),如果导航出然后返回页面,则面板网格包含新数据。

我究竟做错了什么?

4

1 回答 1

0

这是我解决此问题的方法。

如果有更好的方法可以做到这一点,请发布更好的解决方案或在评论中告诉我。理想情况下,我想摆脱支持 bean 中的行,在该行中我通过 ID 获取组件以便对其进行操作。我会认为绑定是为了这个目的?

任何帮助,将不胜感激。


支持豆

@ManagedBean(name = "dataTableTesterBean")
@RequestScoped
public class DataTableTesterBean {
    private DataTable dataTable;
    private ListDataModel<String[]> dataModel;

    public String initDataTable() {
        buildDataModel();
        buildDataTable();
        return "";
    }

    public ListDataModel<String[]> getDataModel() {
        return dataModel;
    }

    public void setDataModel(ListDataModel<String[]> dataModel) {
        this.dataModel = dataModel;
    }

    public DataTable getDataTable() {
        return dataTable;
    }

    public void setDataTable(DataTable dataTable) {
        //do nada
    }

    private Column buildColumn(String colTitle, String colValueExpr) {
        //add columns so the datatable knows what to display
        Column col = (Column) JsfUtil.createComponent(Column.COMPONENT_TYPE);
        UIOutput title = (UIOutput) JsfUtil.createComponent(UIOutput.COMPONENT_TYPE);
        title.setValue(colTitle);
        col.getFacets().put("header", title);
        //setup the field that will display the column data
        ValueExpression val = JsfUtil.createValueExpression(colValueExpr, Object.class);
        HtmlOutputText display = (HtmlOutputText) JsfUtil.createComponent(HtmlOutputText.COMPONENT_TYPE);
        display.setValueExpression("value", val);
        col.getChildren().add(display);
        return col;
    }

    private void buildDataModel() {
        //build up the data
        List<String[]> data = new ArrayList<>();
        data.add(new String[]{"A", "123", "apples"});
        data.add(new String[]{"B", "456", "oranges"});
        data.add(new String[]{"C", "789", "bananas"});
        data.add(new String[]{"D", "987", "lemons"});
        data.add(new String[]{"E", "654", "mangoes"});
        dataModel = new ListDataModel(data);
    }

    private void buildDataTable() {
        //The following line should work, don't know why it doesn't
        //dataTable = (DataTable) JsfUtil.createComponent(DataTable.COMPONENT_TYPE);
        dataTable = (DataTable) JsfUtil.getUIComponent("frmTester:myDataTable");

        dataTable.setVar("item");

        Column abcCol = buildColumn("ABCs", "#{item[0]}");
        dataTable.getColumns().add(abcCol);

        Column numCol = buildColumn("Nums", "#{item[1]}");
        dataTable.getColumns().add(numCol);

        Column fruitCol = buildColumn("Fruits", "#{item[2]}");
        dataTable.getColumns().add(fruitCol);
    }
}

JSF 页面

<h:form id="frmTester">
<h:commandButton value="Do Stuff" action="#{dataTableTesterBean.initDataTable}"/>
<p:dataTable id="myDataTable" value="#{dataTableTesterBean.dataModel}" binding="#{dataTableTesterBean.dataTable}" />
</h:form>

于 2012-11-01T17:09:14.453 回答