2

複合コンポーネント内で Ajax を使用すると問題が発生しました (clientBehavior 属性を使用してカスタム コンポーネントを Ajax 化するのではなく)。

ページが最初にレンダリングされるときに、DOM に存在する必要がある ajax リクエストのターゲットという古い問題に遭遇しました。

カスタム コンポーネントにはいくつかの内部 ajax インタラクションがありますが、最初に render=false である div からアクセスされ、ajax は動作を停止します。通常、サーバー ログにエラー メッセージはありません。

この簡単な例は、問題を示しています。showPanel プロパティが最初に true に設定されている場合は、テキストを入力し、プッシュ リンクをクリックして、画面上で更新されたテキストを確認できます。すべて問題ありません。showPanel が false に設定されている場合、パネルを表示するトグル ボタンを押すことはできますが、「プッシュ」リンクは機能しなくなります。

この複合材が、完全にカプセル化された個別のコンポーネントとして機能できれば、明らかに有益です。

これを回避する方法があるかどうか誰かが知っていますか? 私はすべて歌って踊るコンポーネントを書くのに何年も費やしましたが、初めてそれを使用しようとするとうまくいきません!

ありがとう。

Mojarra 2.0.4 Glassfish 3.0.1 IE8/Chrome。

index.xhtml

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:sqcc="http://java.sun.com/jsf/composite/sqcc"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core">
    <h:head>
        <title>Facelet Title</title>
    </h:head>
    <h:body>
        <h:form prependId="false">
            <h:panelGroup id="ajaxTarget">
                <h:panelGroup rendered="#{indexBean.showPanel}">
                    <sqcc:testcomp value="#{indexBean.text}"/>
                </h:panelGroup>
            </h:panelGroup>
            <h:commandButton value="Toggle" action="#{indexBean.togglePanel}">
                <f:ajax render="ajaxTarget"/>
            </h:commandButton>
        </h:form>
    </h:body>
</html>

リソース/sqcc/testcomp.xhtml

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:cc="http://java.sun.com/jsf/composite"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core">

    <!-- INTERFACE -->
    <cc:interface>
        <cc:attribute name="value"/>
    </cc:interface>

    <!-- IMPLEMENTATION -->
    <cc:implementation>
        <div id="#{cc.clientId}">
            <h:form prependId="false">
                <h:inputText id="input1" value="#{cc.attrs.value}"/>
                <h:outputText id="output1" value=" #{cc.attrs.value}"/><br/>
                <h:commandLink value="push">
                    <f:ajax execute="input1" render="output1"/>
                </h:commandLink>
            </h:form>
        </div>
    </cc:implementation>
</html>

IndexBean.java

import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

@ManagedBean
@ViewScoped
public class IndexBean implements Serializable {

    public IndexBean() {
    }

    private boolean showPanel = true;
    private String text;

    public String togglePanel() {
        showPanel = !showPanel;
        return null;
    }

    public boolean isShowPanel() {
        return showPanel;
    }

    public void setShowPanel(boolean showPanel) {
        this.showPanel = showPanel;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }
}

[終わり]

4

1 に答える 1

1

私自身の質問に答える必要はありませんが、数週間後にこれに戻ってきました。最初の投稿の大きな間違いは、誰もが知っているように、必ずしも最初のページの読み込み時にではなく、Ajax ターゲットをレンダリングするだけでよいということでした。私は疲れていたに違いない。

外部コンテナーが最初にレンダリングされていない場合に「複合コンポーネント内の ajax」が機能しない、私のテスト アプリケーションで示された動作は、実際には正しく再現可能でしたが、複合コンポーネント実装内のロジックが独自のフォーム内にある場合に限られます。 . cc から h:form を取り出すと、すべて問題ありません。

ブレンダン。

于 2011-03-14T22:35:47.153 に答える