2

コンポーネントバインディングとclientIdプロパティを使用して、JavaScriptコード内のコンポーネントを検索します。次のようになります。

<div data-for="@parent" data-example="#{componentBindings.myInput.clientId}" />
...
<h:inputText binding="#{componentBindings.myInput}" value="#{myBean.myProperty}" />

これに関する唯一の問題は、jsfがinputTextフィールドのid属性をレンダリングしないことがあるため、jsコードでclientIdを知っていても、クライアント側にid属性がないため、要素を見つけることができないことです。

  1. 自動生成されたidタグをレンダリングするための要件は何ですか?
  2. jsfにすべてのcliendIdを自動的にレンダリングさせる方法はありますか?(faces-configエントリのように)
  3. 個々の要素のclientIdが(明示的にIDを指定せずに)レンダリングされるようにする方法はありますか?

アップデート

私はトリックを使って自分の道を見つけました:

<span id="#{componentBindings.myInput.clientId}">
    <h:inputText binding="#{componentBindings.myInput}" value="#{myBean.myProperty}" />
</span>

この場合、提案されているように名前を使用するなど、より良い方法がありますが、ajaxでレンダリングする入力フィールドでない場合は、便利な場合があります。たとえば、ファセットの場合:

<!-- myComponent.xhtml -->
<!-- ... -->
<cc:interface>
    <cc:facet name="someFacet" required="true" />
</cc:interface>
<cc:implementation>
    <h:form>
        <cc:renderFacet name="someFacet"/>
    </h:form>
</cc:implementation>

<!-- page.xhtml -->
<!-- ... -->
<my:myComponent>
    <f:facet name="someFacet">
        <h:inputText />
        <!-- ... -->
    </f:facet>
</my:myComponent>

コンポーネントツリーを見ると、ファセットがフォームにネストされておらず、ccの直接の子であることがわかります。したがって、ajaxを使用してccを実行すると便利です。

<!-- myComponent.xhtml -->
<!-- ... -->
<cc:interface>
    <cc:facet name="someFacet" required="true" />
</cc:interface>
<cc:implementation>
    <h:form>
        <cc:renderFacet name="someFacet"/>
        <h:commandLink>
            <f:ajax execute=":#{cc.clientId}" render=":#{cc.clientId}" />
        </h:commandLink>
    </h:form>
</cc:implementation>

ただし、クライアント側に要求されたIDを持つ要素がないため、これは不正な形式のxml例外をスローします。このトリックを使用すると、それを機能させることができます:

<cc:interface>
    <cc:facet name="someFacet" required="true" preferred="true"/>
</cc:interface>

<cc:implementation>
    <span id=#{cc.clientId}>
        <h:form>
            <cc:renderFacet name="someFacet"/>
            <h:commandLink>
                <f:ajax execute=":#{cc.clientId}" render=":#{cc.clientId}" />
            </h:commandLink>
        </h:form>
    </span>
</cc:implementation>

私はおそらくこの回避策を見つけた最初の人ではありませんが、どこにも見つからなかったので共有することにしました

4

1 に答える 1

1

MojarraのHtmlBasicRendererソースコード(2.1.17の672行目から)から:

/**
 * @param component the component of interest
 *
 * @return true if this renderer should render an id attribute.
 */
protected boolean shouldWriteIdAttribute(UIComponent component) {

    // By default we only write the id attribute if:
    //
    // - We have a non-auto-generated id, or...
    // - We have client behaviors.
    //
    // We assume that if client behaviors are present, they
    // may need access to the id (AjaxBehavior certainly does).

    String id;
    return (null != (id = component.getId()) &&
                (!id.startsWith(UIViewRoot.UNIQUE_ID_PREFIX) ||
                    ((component instanceof ClientBehaviorHolder) &&
                      !((ClientBehaviorHolder)component).getClientBehaviors().isEmpty())));
}

したがって、コンポーネントに属性が設定されている場合、またはコンポーネントにクライアント動作ホルダー(読み取り:子)がある場合にのみ、HTML要素のid属性がレンダリングされます。id<f:ajax>

したがって、実際には自分で指定する必要があります。

<h:inputText id="foo" ... />

それ以外の場合は、JSコードを変更して、のname代わりに入力を選択するようにしidます。

于 2013-01-28T16:40:05.203 に答える