1. ホーム
  2. java

[解決済み] p:dashboardモデルの動的な更新に関する問題

2022-02-03 23:06:44

質問

あるDashboardを開発しようとしています。最初に空のダッシュボードを作成し、そこに動的に要素を埋めていきたいのですが、どうすればいいですか?

まず、空のダッシュボードを作成します。 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で、ユーザーがMODELに挿入したウィジェットの数を確認します。
  2. 2番目のforeachは、すべてのパネルに"booking"という異なる要素でpopolateします。

アプリケーションの起動時にロードされる空のモデルを作成します。

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;

}

この部分では、いろいろなことをしていますが、重要なのは "create"で、新しい空のカラムを追加しています。私は、Javaコードの中で使用するDashboardColumnのリストを作成します。 columnDashboard .


モデル内にウィジェットを追加するために、特定のメニューを作成します。 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>

誰かがWidgetを追加することを決めたら、私はメソッドでモデルを修正します。 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);
            }
        }}

この方法はすでに検証していますが、結果を可視化することができません。 DashboardのモデルをUPDATEするにはどうしたらいいでしょうか? 私はすでにこれを試していますが、私はこれが動作しないはずだと思う;(

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 Dashboardを動的にポップアップするコード全体を共有します。ありがとうございます、困ってます :(

どのように解決するのですか?

私はこの解決策を見つけました。

を作成する際に、私が直面したのと同じような難しさを感じる人のための例です。 ダイナミックダッシュボード (すべてがダイナミック)。

私の問題質問

プロジェクトは: 空のダッシュボードを表示すると、ユーザーは右側の フォーム を付けて 利用可能な会議室 . 会議室を1つクリックすると、モデルが更新され、右の列にパネルが表示されます(IDが事前に割り当てられています)。 私は、すべてのID、列の数、パネルの数、各パネル内に可視化された要素の数を動的に割り当てます。


まず Java DashboardModel 空のカラムがあります。

    private DashboardModel model;
    private List<DashboardColumn> dashboardColumn;

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

論理的には ゲッター セッター をモデルとして使用します。 各カラムを簡単に管理するために、DashboardColumnのListを作成します。

meetingRoomByOfficeという会議室オブジェクトのリストをPopolateします。 このリストは アクションメニュー を使用して、メニュー内に動的な要素を作成します。

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

私は、各カラムのID(column1 = 1オフィスID)とリスト内の実際の位置(ID : 450 - リスト内の位置0など)を保存するために二次元配列をpopolateします。

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の"name"で一つずつブラウズしていきます。
  2. IDを取得するために、会議室の名前を分割したIDを生成するgetMenuItemIdという特定のメソッドを実行しました。このようなものです。名前 : サラデモ --> ID : Sala__Demo
  3. アクションはモデルを修正するためにmainメソッドを呼び出しますが、それについてはこのリストの後で説明します。
  4. update ="widgetBookingReception"> は、FORM全体を更新することが重要です

メソッド onAddPanel

私は2つのメインオブジェクトを持つ特別なクラスを持っています。

  • idWidget 文字列であること
  • 会議室 オブジェクトであることを示す MeetingRoom

まず、アンダースコア1つでIDを作成します。

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

TMPオブジェクトを作成し、それをTMPオブジェクトに追加した後、ユーザーによってモデルに挿入されたウィジェットのリスト内に"widget"を挿入します。これは、ウィジェットの紛失を防ぐために重要です。

    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の中でNull Listや空のListを渡してはいけないということです。私は WHEN を使えば、それを防ぐことができます。

もし何か質問があれば、喜んでお答えしますし、私のコードの一部も共有します。 また会いましょう :D