p:dashboard模型动态更新的问题

时间:2018-10-23 14:32:42

标签: java jsf primefaces jsf-2 jsf-2.2

我正在尝试开发特定的仪表板。我想创建一个初始的空仪表板,并用元素动态填充它。

首先,我创建一个空的仪表板: XHTML --->

 <p:dashboard id="dash" model ="#{homeReceptionDashboardBck.model}">
            <c:forEach 
                  items="#{homeReceptionDashboardBck.widgets}" 
                  var="widgetsElement">
                <p:panel id = "widgetsElement.idWidget" header="widgetsElement.name">
                    <c:forEach 
                           items="#{homeReceptionDashboardBck.uploadBooking(widgetsElement)" 
                           var="bookings">
                                <h:outputText value="#{booking.owner.ragioneSociale}"> 
                                </h:outputText>
                    </c:forEach>
                </p:panel>
            </c:forEach>
    </p:dashboard>

这是我用来使用 填充和动态创建每个面板的代码。

  1. 第一拳foreach验证用户将多少个小部件插入到模型中
  2. 第二个foreach使用称为“预订”的不同元素填充每个面板。

我创建了一个空模型,该模型会在应用程序启动时加载:

for(i = 0;i<officesList.size();i++) {
    DashboardColumn columnTmp = new DefaultDashboardColumn();
    model.addColumn(columnTmp);

    columnDashboard.add(columnTmp);
    List<MeetingRoom> tempMeetingRoom = new ArrayList<>();
    tempMeetingRoom = meetingmr.getAllByOffice(
                            officesList.get(i).getId(), 
                            true, 
                            JSFUtil.getActiveUser());
    for(x = 0;x<tempMeetingRoom.size();x++)
    {
        //popolo la lista che mi serve all'inizio per la lista dei Panel da inserire
        meetingRoomByOffice.add(tempMeetingRoom.get(x));
    }

    officePositionAndColumn[i][0] = (int) (long) officesList.get(i).getId();
    officePositionAndColumn[i][1] = i;

}

在代码的这一部分中,我正在做很多事情,但是重要的是“创建”并添加一个新的空列。我创建了一个DashboardColumn列表,以在名为 columnDashboard 的Java代码中使用。


我创建一个特定的菜单以在模型内添加小部件: XHTML --->

<smifn:actionsMenu id="tableAddMeetingRoom" styleClass="col-xs-8 col-md-12 text-right"
                    title="#{msg['booking.add_meeting_room']}">
    <c:forEach items="#{homeReceptionDashboardBck.meetingRoomByOffice}" 
                var="meetingRoomElement">
        <p:menuitem id="#{homeReceptionDashboardBck.getMenuItemId(meetingRoomElement)}" 
                    actionListener="#{homeReceptionDashboardBck.onAddPanel(meetingRoomElement)}" 
                    process="@this" partialSubmit="true"
                    value="#{meetingRoomElement.name}" 
                    icon="icon-add-3" 
                    iconPos="left"
                    >
            <p:ajax process="widgetBookingReception" update="widgetBookingReception"/>
        </p:menuitem>       <!--  oncomplete="PF('bookingSelect').show()"-->
    </c:forEach>
</smifn:actionsMenu>

当某人决定添加小部件时,我使用 onAddPanel

方法修改模型

JAVA ---->

public void onAddPanel(MeetingRoom panelSelected) {
    int i;
    //splitto il nome per creare l'id
    String [] nameMeetingRoom = panelSelected.getName().split(" ");
    String idWidget = nameMeetingRoom[0]+"_"+nameMeetingRoom[1];
    //oggetto di tipo DashboardWidget
    DashboardWidget tmp = new DashboardWidget();
    //imposto l'id, nome della stanza e l'ufficio relativo
    tmp.setIdWidget(idWidget);
    tmp.setName(panelSelected.getName());
    tmp.setOffice(panelSelected.getOffice());
    //aggiungo alla lista dei widget l'oggetto relativo
    widgets.add(tmp);
    //stringa per la posizione della colonna
    int columnPosition = -1;
    //faccio un for per passare tutte le colonne relative
    for(i = 0;i<officePositionAndColumn.length;i++)
    {
        //se l'id che era stato impostato è uguale a quello passato 
        if(officePositionAndColumn[i] [0] == panelSelected.getOffice().getId())
            //posizione della colonna che va da 0 a n.
            columnPosition = officePositionAndColumn[i][1];
    }
    //se è stato trovata la posizione della colonna
    if(columnPosition>=0) {
        //mi ricavo la colonna 
        DashboardColumn columnSelected = new DefaultDashboardColumn();
        columnSelected = columnDashboard.get(columnPosition);
        //imposto l'id al widget
        columnSelected.addWidget(idWidget);
        //sovrascrivo la colonna con quella modificata
        columnDashboard.set(columnPosition, columnSelected);
        //reimposto il modello e ricarico le colonne
        setModel(new DefaultDashboardModel());
        for(i = 0;i<columnDashboard.size();i++)
        {
            this.model.addColumn(columnDashboard.get(i));
        }

        for(i = 0;i<meetingRoomByOffice.size();i++)
        {
            if(meetingRoomByOffice.get(i).equals(panelSelected))
            {
                meetingRoomByOffice.remove(i);
            }
        }}

我已经验证了此方法,但是无法看到结果。 如何更新仪表板的模型? 我已经尝试过了,但是我认为这不应该起作用;(

public void createDashboardDinamically(){

    int i;
    FacesContext fc = FacesContext.getCurrentInstance();
    Application app = fc.getApplication();

    dashboard = (Dashboard) app.createComponent(
                                    fc, 
                                    "org.primefaces.component.Dashboard",
                                    "org.primefaces.component.DashboardRenderer");
    dashboard.setId("dash");
    dashboard.setModel(model);

    Panel panel1 = (Panel) app.createComponent(
                                fc, 
                                "org.primefaces.component.Panel", 
                                "org.primefaces.component.PanelRenderer");
    panel1.setId("Sala_Demo");
    panel1.setToggleable(true);
    panel1.setClosable(true);
    panel1.setHeader("Sala Demo");

    for(i = 0;i<widgets.size();i++)
    {
        Panel panel = (Panel) app.createComponent(
                                    fc, 
                                    "org.primefaces.component.Panel", 
                                    "org.primefaces.component.PanelRenderer");
        panel.setId(widgets.get(i).getIdWidget());
        panel.setToggleable(true);
        panel.setClosable(true);
        panel.setHeader(widgets.get(i).getName());
        getDashboard().getChildren().add(panel);

    }

有人可以帮我吗?如果可行,我将共享整个代码以动态填充PrimeFaces仪表板。非常感谢,我被困住了:(

1 个答案:

答案 0 :(得分:1)

我找到了这个解决方案:

对于所有在创建 动态仪表板 (一切都是动态的)时遇到相同困难的人,这是一个示例。

My problem question

项目为: :显示一个空的仪表板,用户将在 FORM < / strong>,并提供会议室的其他成员。 单击一间会议室后,将更新模型,并在右栏中显示面板(预分配其ID)。 我动态分配每个ID,列数,面板数和每个面板中可视化的元素数。


首先,使用空列填充 Java DashboardModel

    private DashboardModel model;
    private List<DashboardColumn> dashboardColumn;

    DashboardColumn columnTmp = new DefaultDashboardColumn();
    model.addColumn(columnTmp);
    columnDashboard.add(columnTmp);

从逻辑上讲,您必须为模型创建 getter setter 。 我创建了DashboardColumn列表,以方便地管理每一列。

定位一个名为meetingRoomByOffice的meetingRoom对象的列表。 此列表对于 actionMenu 是必需的,以便在菜单内创建动态元素。

for(x = 0;x<tempMeetingRoom.size();x++)
                {
                meetingRoomByOffice.add(tempMeetingRoom.get(x));
                }

我填充一个二维数组以保存每一列的ID(column1 = 1 office ID)以及列表内的实际位置(ID:450-列表内0的位置,等等)

for(i = 0;i<officesList.size();i++) {
            officePositionAndColumn[i][0] = (int) (long) officesList.get(i).getId();
            officePositionAndColumn[i][1] = i;

            }

此后,在XHTML中创建 元素 第一个是actionMenu

注意 我有一个个性化的个人,没有特殊修改

<smifn:actionsMenu id="tableAddMeetingRoom" styleClass="col-xs-8 col-md-12 text-right"
                    onclick="@this.update()"
                    title="#{msg['booking.add_meeting_room']}">
                    <c:forEach items="#{homeReceptionDashboardBck.meetingRoomByOffice}" var="meetingRoomElement">
                        <p:menuitem id="#{homeReceptionDashboardBck.getMenuItemId(meetingRoomElement)}" 
                            action="#{homeReceptionDashboardBck.onAddPanel(meetingRoomElement)}" 
                            process="@this"
                            value="#{meetingRoomElement.name}" 
                            icon="icon-add-3" 
                            iconPos="left"
                            update ="widgetBookingReception">
                        </p:menuitem>       <!--  oncomplete="PF('bookingSelect').show()"-->
                    </c:forEach>
                </smifn:actionsMenu>
  1. 首先foreach --->获取一个元素列表,并使用MeetingRoomElement的“名称”逐一浏览它们
  2. 要获取ID,我已经执行了一个特殊的方法调用getMenuItemId,该方法生成一个ID为会议室名称的ID,该ID被拆分了。这样的东西:名称:Sala Demo-> ID:Sala__Demo
  3. 操作会调用main方法修改模型,我将在此列表后进行解释。
  4. update ="widgetBookingReception">对于更新整个表单很重要

onAddPanel上的方法

我有一个带有两个主要对象的特殊类:

  • idWidget ,它是一个字符串
  • meetingRoom ,它是一个MeetingRoom对象

首先,我创建一个带下划线的ID

    String [] nameMeetingRoom = panelSelected.getName().split(" ");
    String idWidget = nameMeetingRoom[0]+"_"+nameMeetingRoom[1];

创建,并将其添加到TMP对象中,之后,将“小部件”插入用户在模型中插入的小部件列表中。这对于避免丢失小部件很重要。

    DashboardWidget tmp = new DashboardWidget();

    tmp.setIdWidget(idWidget);
    tmp.setName(panelSelected.getName());
    tmp.setOffice(panelSelected.getOffice());

    widgets.add(tmp);

现在,我将在列表中找到位置,更新模型,并在菜单中使用listOfMeetingRoom。

for(i = 0;i<officePositionAndColumn.length;i++)
    {
        //se l'id che era stato impostato è uguale a quello passato 
        if(officePositionAndColumn[i] [0] == panelSelected.getOffice().getId())
            //posizione della colonna che va da 0 a n.
            columnPosition = officePositionAndColumn[i][1];
    }
    //se è stato trovata la posizione della colonna
    if(columnPosition>=0) {
        //mi ricavo la colonna 
        DashboardColumn columnSelected = new DefaultDashboardColumn();
        columnSelected = columnDashboard.get(columnPosition);
        //imposto l'id al widget
        columnSelected.addWidget(idWidget);
        //sovrascrivo la colonna con quella modificata
        columnDashboard.set(columnPosition, columnSelected);
        //reimposto il modello e ricarico le colonne
        setModel(new DefaultDashboardModel());
        for(i = 0;i<columnDashboard.size();i++)
        {
            this.model.addColumn(columnDashboard.get(i));
        }

        for(i = 0;i<meetingRoomByOffice.size();i++)
        {
            if(meetingRoomByOffice.get(i).equals(panelSelected))
            {
                meetingRoomByOffice.remove(i);
            }
        }

这就是我更新整个模型的方式。 但是现在 我们必须将其更新 到XHTML中。

我创建了一个完整的动态仪表板,这是代码:

<p:dashboard widgetVar="dash" model ="#{homeReceptionDashboardBck.model}">
<c:when test="not empty #{homeReceptionDashboardBck.widgets}">
            <c:forEach items="#{homeReceptionDashboardBck.widgets}" var="Element">

                <p:panel id="#{Element.idWidget}" header="#{Element.name}">
                <c:when test="not empty #{homeReceptionDashboardBck.uploadBooking(Element)}">
                    <c:forEach items="#{homeReceptionDashboardBck.uploadBooking(Element)}" var="row">
                                <h:outputText value="#{homeReceptionDashboardBck.getEventGeneralInfo(row)}"> </h:outputText>
                                <h:outputText> <br/></h:outputText>
                    </c:forEach>
                </c:when>
                <c:otherwise>
                    <c:when test="#{homeReceptionDashboardBck.uploadBooking(Element)}">
                            <h:outputText value="Nessun evento prenotato"> </h:outputText>
                            <h:outputText> <br/></h:outputText>
                        </c:when>
                </c:otherwise>
                </p:panel>
            </c:forEach>

</c:when>
    </p:dashboard>

请注意,在foreach内部您不能传递空List或空List。我使用 WHEN 来防止这种情况。

如果您有任何问题,我很乐意回答并分享部分代码。 待会见:D