2016-04-11 20 views
2

フロントエンドコンポーネントのJavaScriptフレームワーク(Aurelia)を既存のJSFアプリケーションに統合する作業を進めています。私は、例えば、出力にカスタムタグを配置するためにJSFレンダラーを使用しています。:JavaScriptフレームワークによるJSFカスタムコンポーネントの登録

@FacesRenderer(componentFamily = "frontend.component", rendererType = "frontend.mytag") 
public class MyTagRenderer extends Renderer { 

    @Override 
    public void encodeEnd(FacesContext context, UIComponent component) throws IOException { 
     final String tag = "my-tag"; 
     int id = (Integer) component.getAttributes().get("id"); 
     ResponseWriter writer = context.getResponseWriter(); 
     writer.startElement(tag, component); 
     writer.writeAttribute("id.bind", id, null); 
     writer.endElement(tag); 
    } 
} 

問題はJSフレームワークを初期化中に、私はタグをブートストラップする必要があるカスタム知る必要があるということです。

class MyTagRenderer { 
    public void encodeEnd(FacesContext context, UIComponent component) { 
     ... 
     ((FrontendComponent) component).setTagName("my-tag:); 
    } 
} 

@ManagedBean 
@RequestScoped 
class FrontendBootstrapHandler { 
    public String getTagList() { 
     List<String> tags = walkRecursive(FacesContext.getCurrentInstance().getViewRoot()); 
     return "'" + String.join("','", tags + "'"; 
    } 
} 

しかし、私は:最初に私は、私のJSFフロントエンドコンポーネントクラスにプロパティとしてタグ名を追加するカスタムレンダラでそれを設定し、リストを取得するためにJSFコンポーネントツリーを歩いて、このサーバ側をやってみましたJSFがページの一部をレンダリングする順序が完全に予測できないことがあり、がsetTagNameの前に呼び出されたことがあることが判明しました。

今のところ私は各カスタムタグの横に<script>スニペットをレンダリングして、タグのリストをクライアントサイドのブートストラップに保つことに決めましたが、これは理想的ではありません。誰も私にもっと優雅なソリューションを提供できますか?

+1

私はaureliaを見てきましたが、AngularJsに似たフレームワークであると思われます。これは完全なMVCフレームワークであり、jQueryとは異なり、JSに構文砂糖を追加します。 JSFはAureliaと同じですが、サーバー側にあります。 AureliaによるJSFを置き換える場合は、マネージドBeanを使用する代わりに、ビュー全体を置き換え、サーバー側に適切なコントローラ(Spring MVCまたはその他のフレームワーク)を配置することをお勧めします。作成するスクリプトは、マネージドBeanの機能を置き換えます。そうでなければ、同時に両方のものを混ぜようとすると、頭痛で終わるように見えます。 –

+1

@Xtreme:JSF/Faceletsは他のフレームワーク用の(ステートレスな)HTMLビューを生成するのに適しています。質問履歴に基づいて、OPはJAX-RSに精通しているようです。そのため、Spring MVC RESTコントローラ(ちょうどの場合)よりも推奨されます。 – BalusC

+0

私が知っていることはすべてですが、JSFからJavaScriptに10年前のレガシーアプリケーションを一晩書き直すことはできません。不都合かもしれませんが、私は当面両者を使用する必要があります。 –

答えて

0

私は、サーバー側のコンポーネントのリストを維持する方法を見つけました。むしろいつでも呼び出すことができレンダラにブートストラップするタグ名を設定するよりも、私はComponentHandlerでそれを設定します。

my.taglib.xml

<tag> 
    <tag-name>my-tag</tag-name> 
    <attribute> 
     <name>id.bind</name> 
     <required>true</required> 
     <type>java.lang.Integer</type> 
    </attribute> 
    <component> 
     <component-type>frontend.component</component-type> 
     <renderer-type>frontend.renderer</renderer-type> 
     <handler-class>frontend.FrontendComponentHandler</handler-class> 
    </component> 
</tag> 

FrontendComponentHandler.java

public class FrontendComponentHandler extends javax.faces.view.facelets.ComponentHandler { 

    public FrontendComponentHandler(ComponentConfig config) { 
     super(config); 
    } 

    @Override 
    public void onComponentCreated(FaceletContext ctx, UIComponent c, UIComponent parent) { 
     FrontendComponent component = (FrontendComponent) c; 
     component.setTagName(tag.getLocalName()); 
    } 
} 

FrontendBootstrapHandler.java

@ManagedBean 
@RequestScoped 
class FrontendBootstrapHandler { 
    public String getTagList() { 
     List<String> tags = walkRecursive(FacesContext.getCurrentInstance().getViewRoot()); 
     return "'" + String.join("','", tags + "'"; 
    } 
} 
関連する問題