2

プログラムでダイアログを表示/呼び出して、これをステージ(実際のブラウザウィンドウ)に追加するにはどうすればよいですか?

2時間ごとにデータベースの更新をトリガーしたい。私はこれをで行いましたTimerTask。これは私にとっては問題なく機能します。タイマータスクは、データベースから必要なすべてのデータを取得します。このタイマータスクがトリガーされる前に、ユーザー(セッションスコープ)がデータベースにアクセスできないように画面を数秒間「ロック」したいと思います(これがどのように機能するかも知っています)。私の問題は、プログラムでダイアログを呼び出す方法がわからない/見つからないことです。


更新このprimefacesダイアログを設定したい:

Dialog dialog = new Dialog(); 
dialog.setAppendToBody(true);
dialog.setModal(true);
dialog.setVisible(true);
dialog.setWidgetVar("generatedDialog");
dialog.setId("fancyDialog");
dialog.setClosable(false);
dialog.setHeader("Getting latest information from the database");
dialog.setDynamic(true);
dialog.setResizable(false);
dialog.setDraggable(false);

ブラウザに表示するにはどうすればよいですか?

4

3 に答える 3

1

プログラムでダイアログを作成する必要はありません。必要なのはプッシュ技術です。つまり、サーバーがクライアントとの対話を開始します。PrimeFacesはすでにこのテクノロジーを備えており、すぐに使用できます。

あなたのニーズの基本的なケースはPrimePush-FacesMessageです:

  • ユーザーが通知を書き込みます。
  • サーバーは通知を受け取ります。
  • 通知は、/notificationsチャネルの下のPushContextに送信されます。
  • チャネルを含むすべてのクライアントに対して/notifications、アクションが実行されます。この場合、チャネルは同じページにのみ存在し、アクションは通知を表示することです。

2つの異なるナビゲーターで同じページを開き、通知を送信することで、この動作をテストできます。すべてのページに通知が表示されます(必要なもののように見えます)。

この例をオンにすると、実行する必要があるのは次のようになります。

  1. すべてのページ(これは本当に面倒な作業ですが、必要なものです)またはマスターページ(テンプレートシステムを使用した場合)にチャネルを設定します。
  2. タイマーは、通知を開始するためにサーバー要求をいくらか呼び出す必要があります。プログラムでファイルをアップロードする方法についてのサンプルがここにありますが、リクエスト1を開始するだけで、パラメータを送信する必要はありません。
  3. タイマーが呼び出すリクエストは、チャネルに通知を追加します。
  4. チャネルは自動的にアクションを実行し、必要なことを実行できます。提供されている例では、うなり声が表示されていますが、を表示するように変更できます<p:dialog>

1ユーザーがこのリクエストを呼び出さないようにするには、タイマー以外のユーザーがリクエストを実行できないようにするフィルターを設定するとよいでしょう。

于 2012-11-03T16:57:55.487 に答える
0

簡単な解決策があります:

  1. まず、マスターページにダイアログを追加します。このダイアログのレンダリングされた属性は、最初にfalseに設定する必要があります。

  2. 次に、コードに従って現在のページを更新します

    protected void refreshPage() { 
        FacesContext fc = FacesContext.getCurrentInstance(); 
        String refreshpage = fc.getViewRoot().getViewId();
    
        ViewHandler ViewH = fc.getApplication().getViewHandler(); 
        UIViewRoot UIV = ViewH.createView(fc,refreshpage);
        UIV.setViewId(refreshpage); 
        fc.setViewRoot(UIV); 
    }
    
  3. 3番目に、TimerTaskクラスに関連するメソッドを使用して上記のメソッドを呼び出し、このTimerTaskクラスに関連するメソッドでダイアログレンダリング属性をtrueに設定します。

それで全部です :)

于 2012-11-03T16:27:19.273 に答える
0

@Luiggi Mendozaのアイデアによると、私は少し立ち往生しています...

私は自分のjsfに以下を追加しました:

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:p="http://primefaces.org/ui"
    xmlns:f="http://java.sun.com/jsf/core"
    template="/templates/layoutUser.xhtml">

    <ui:define name="content">

        <p:growl widgetVar="growl" showDetail="true" />

        <h:form>
        Fanciest Page ever          
        </h:form>

        <p:socket onMessage="handleMessage" channel="/notifications" />

        <script type="text/javascript">
            function handleMessage(facesmessage) {
                facesmessage.severity = 'info';

                growl.show([ facesmessage ]);
            }
        </script>

    </ui:define>
</ui:composition>

セッションスコープのBeanでTimerTaskを呼び出しています。

@PostConstruct
    public void initLazyModel() {
        getTimerMB().startTimer(this);
        System.out.println("Timer started");

    }

私のタイマーは次のようになります。

@ManagedBean(name = "timerMB")
@SessionScoped
public class TimerManagedBean extends TimerTask {

    private int counter;
    private Timer timer;
    private ArtikelManagedBean artikelMB;

    public void startTimer(ArtikelManagedBean artikelMB){
        this.artikelMB = artikelMB;
        this.timer = new Timer(); 
        Calendar date = Calendar.getInstance();  
        date.set(2012, 3, 28, 21, 28);
        //execute every 10 seconds  
        timer.schedule(this, date.getTime(), 10000);
    }

    @PreDestroy
    public void cancelTimer(){
        this.timer.cancel();
        System.out.println("UpdateTimer cancelled!");
    }

    @Override
    public void run() {
        counter++;
        System.out.println("Upadatetimer started: "+ new Date()+" ("+counter+")");
            PushContext pushContext = PushContextFactory.getDefault()
            .getPushContext();

    pushContext.push("/notifications", new FacesMessage("Simple",
            "Test"));
    }
}

うーん...何も起こらないけど、何か起こるはずだよね?それは私に「シンプル」と「テスト」で通知を与えるはずです、私は推測します...

アップデート:

Luiggi Mendozaありがとうございます!ダイアログを表示するための非常に簡単な方法で管理しました(サーバーサイドと呼びます)。次のサーブレットをweb.xmlに追加しました。

<servlet>
    <servlet-name>Push Servlet</servlet-name>
    <servlet-class>org.primefaces.push.PushServlet</servlet-class>

    <init-param>
    <param-name>org.atmosphere.useBlocking</param-name>
    <param-value>true</param-value>
</init-param>

    <init-param>
        <param-name>org.atmosphere.cpr.sessionSupport</param-name>
        <param-value>true</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>Push Servlet</servlet-name>
    <url-pattern>/primepush/*</url-pattern>
</servlet-mapping>
于 2012-11-03T21:17:14.273 に答える