3

私は自分の JSF2UIComponentとそれに関連するレンダラーを書くのに忙しいです。私のすべてUIComponentの道具ClientBehaviorHolder。私が理解していないのは、実際にレンダリングする方法ClientBehaviorHolderです。

たとえば、次のコードClientBehaviorHolderは Mojarra で がどのようにレンダリングされるかを示しています。

private static void renderHandler(FacesContext context,
                                  UIComponent component,
                                  Collection<ClientBehaviorContext.Parameter> params,
                                  String handlerName,
                                  Object handlerValue,
                                  String behaviorEventName,
                                  String submitTarget,
                                  boolean needsSubmit,
                                  boolean includeExec)
    throws IOException {

    ResponseWriter writer = context.getResponseWriter();
    String userHandler = getNonEmptyUserHandler(handlerValue);
    List<ClientBehavior> behaviors = getClientBehaviors(component, behaviorEventName);

    // Don't render behavior scripts if component is disabled
    if ((null != behaviors) && 
        (behaviors.size() > 0) && 
         Util.componentIsDisabled(component)) {
        behaviors = null;
    }

    if (params == null) {
        params = Collections.emptyList();
    }
    String handler = null;
    switch (getHandlerType(behaviors, params, userHandler, needsSubmit, includeExec)) {

        case USER_HANDLER_ONLY:
            handler = userHandler;
            break;

        case SINGLE_BEHAVIOR_ONLY:
            handler = getSingleBehaviorHandler(context, 
                                               component,
                                               behaviors.get(0),
                                               params,
                                               behaviorEventName,
                                               submitTarget,
                                               needsSubmit);
            break;

        case SUBMIT_ONLY:
            handler = getSubmitHandler(context, 
                                       component,
                                       params,
                                       submitTarget,
                                       true);
            break;

        case CHAIN:
            handler = getChainedHandler(context,
                                        component,
                                        behaviors,
                                        params,
                                        behaviorEventName,
                                        userHandler,
                                        submitTarget,
                                        needsSubmit);
            break;
        default:
            assert(false);
    }


    writer.writeAttribute(handlerName, handler, null);
}

送信ハンドラーの場合、Mojarra はmojarra.jsfcljsjavascript、UIParameters、およびその他のスクリプトを追加します。チェーン ハンドラーの場合は、jsf.util.chainが使用されます。

私の質問は:

  • ハンドラーをチェーンでレンダリングする必要があるか、単一の動作またはユーザー固有のハンドラーをレンダリングする必要があるかをどのように判断しますか?
  • mojarra.jsfcljsモハラにのみ固有です。PrimeFaces には独自の実装があり、Apache Tomahawk も同様です。質問は: は何をしmojarra.jsfcljs、その用途は何ですか? これは、自分用に書くことができるようにするためですか? また、どこで実装を見つけることができますmojarra.jsfcljsか?
  • レンダリングする仕様はClientBehaviorHolder

よろしくお願いします。

4

1 に答える 1

5

ハンドラーをチェーンでレンダリングする必要があるか、単一の動作またはユーザー固有のハンドラーをレンダリングする必要があるかをどのように判断しますか?

エンドユーザー (コンポーネントを使用している JSF 開発者) が次のようにプログラミングしたとします。

<your:component onclick="return foo()" />

そして、最終的にはコンポーネント自身の目的のためにレンダリングするつもりでした:

<someHtmlElement onclick="jsf.ajax.request(...); return false;" />

onclick次に、コンポーネントの前にエンドユーザーを連結することはできませjsf.ajax.request()

<someHtmlElement onclick="return foo(); jsf.ajax.request(...); return false;" />

が返されたとしてもtrue、コンポーネントjsf.ajax.requestはまったく呼び出されません。あなたは最終的に次のようなものになりたいと思っています:

<someHtmlElement onclick="if returnsTrue('return foo();') { jsf.ajax.request(...); } return false;" />

それはまさにjsf.util.chain()、隠れてやっていることです。


mojarra.jsfcljsモハラにのみ固有です。PrimeFaces には独自の実装があり、Apache Tomahawk も同様です。質問は: は何をしmojarra.jsfcljs、その用途は何ですか? これは、自分用に書くことができるようにするためですか? また、どこで実装を見つけることができますmojarra.jsfcljsか?

ファイルの中にありjsf.jsます。これを見つける簡単な方法は、<f:ajax>埋め込まれた JSF ページを開き、生成された<head>ソース<script>でその URL を調べることです。このファイルはデフォルトで圧縮されています。javax.faces.PROJECT_STAGEcontext param をに設定するDevelopmentと、これは縮小されずに提供されます。関数のタスクはjsfcljs()、必要なパラメーターを使用して親フォームを送信することです。これは、Mojarra 2.1.21 からの関連性の抜粋です。

/*
 * This is called by command link and command button.  It provides
 * the form it is nested in, the parameters that need to be
 * added and finally, the target of the action.  This function
 * will delete any parameters added <em>after</em> the form
 * has been submitted to handle DOM caching issues.
 *
 * @param f - the target form
 * @param pvp - associative array of parameter
 *  key/value pairs to be added to the form as hidden input
 *  fields.
 * @param t - the target of the form submission
 */
mojarra.jsfcljs = function jsfcljs(f, pvp, t) {

レンダリングする仕様はClientBehaviorHolder

ClientBehavior#getScript()自動生成されたスクリプトを取得するために使用します。ClientBehaviorContextを使用して作成できる引数が必要ClientBehaviorContext#createClientBehaviorContext()です。などの適切な HTML 属性にレンダリングするのは、ユーザーの責任onclickです。

FacesContext context = FacesContext.getCurrentInstance();
UIComponent inputOrCommandComponent = ...; // Your component.
String event = "click"; // Just the particular HTML DOM event name you need to listen on.

ClientBehaviorContext clientBehaviorContext = ClientBehaviorContext.createClientBehaviorContext(context, component, event, component.getClientId(context), null);
StringBuilder builder = new StringBuilder();

for (ClientBehavior behavior : component.getClientBehaviors().get(event)) { // Collect all <f:ajax> declarations on the given event.
    builder.append(behavior.getScript(clientBehaviorContext));
    builder.append(';');
}

String script = builder.toString();
// Write it to the desired HTML attribute.

この方法で JSF 実装固有のスクリプトを作成することについて心配する必要はまったくないことに注意してください。それらはあなたのために生成されます。

結局のところ、ClientBehaviorHolderこれは ajax サポートの単なる抽象化です。これにより、開発者は<f:ajax>コンポーネントにネストできます。すべての標準 JSFUIInputおよびUICommandコンポーネントがそれを実装します。

于 2013-06-29T19:54:37.783 に答える