在JSF Ajax响应XML插入自定义标签 [英] Inserting custom tag in JSF Ajax response XML

查看:99
本文介绍了在JSF Ajax响应XML插入自定义标签的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Consoder以下code:

 < H:的commandButton值=做行动=#{testBacking.do}>
   < F:AJAX执行=@所有渲染=@所有监听器=#{testBacking.listener}/>
< / H:的commandButton>
 

我想有(与基于服务器的逻辑值)的自定义标签,在Ajax响应XML,类似如下:

 < isValidationFailed>真< / isValidationFailed>
 

我可以用这个数据来重新启用按钮(被禁用时阿贾克斯开始,以避免重复点击)如果验证失败。

我怎样才能做到这一点(preferably不使用任何JSF第三方库)?

编辑:

这个例子code,更precisely,应该是这样的:

 < H:的commandButton ID =myButton的值=做行动=#{testBacking.do}>
 < F:AJAX执行=ID1渲染=ID2 myButton的监听器=#{testBacking.listener}/>
< / H:的commandButton>
 

解决方案

这是唯一可能与自定义的 PartialViewContext 您使用的 PartialViewContextFactory 。自定义 PartialViewContext 应依次返回一个自定义的 PartialResponseWriter 的<一个href="http://docs.oracle.com/javaee/6/api/javax/faces/context/PartialViewContext.html#getPartialResponseWriter%28%29"相对=nofollow> PartialViewContext#getResponseWriter() 。在此自定义 PartialResponseWriter ,你应该能够扩展添加到XML响应通过调用<一href="http://docs.oracle.com/javaee/6/api/javax/faces/context/PartialResponseWriter.html#startExtension%28java.util.Map%29"相对=nofollow> startExtension() 和<一href="http://docs.oracle.com/javaee/6/api/javax/faces/context/PartialResponseWriter.html#endExtension%28%29"相对=nofollow> endExtension() 在<一个href="http://docs.oracle.com/javaee/6/api/javax/faces/context/PartialResponseWriter.html#endDocument%28%29"相对=nofollow> 调用endDocument() 。是这样的:

  @覆盖
公共无效调用endDocument()抛出IOException异常{
    地图&LT;字符串,字符串&GT;属性=新的HashMap&LT;字符串,字符串&GT;();
    attributes.put(名1,值1);
    attributes.put(名2,值2);
    startExtension(属性);
    写(Lorem存有);
    endExtension();
    super.endDocument();
}
 

这将随后结束在XML响应,

&LT;扩展名1 =值1名称2 =值2&GT; Lorem存有&LT; /扩展&GT;

这是可用,穿越由 data.responseXML jsf.ajax.addOnEvent()的功能。


下面是一个完整的开球例如如何,你可以在您的特定情况下使用它:

MyPartialViewContextFactory ,它提供了自定义的局部视图方面:

 公共类MyPartialViewContextFactory扩展PartialViewContextFactory {

    私人PartialViewContextFactory包裹;

    公共MyPartialViewContextFactory(PartialViewContextFactory包裹){
        this.wrapped =包裹;
    }

    @覆盖
    公共PartialViewContext getPartialViewContext(FacesContext的上下文){
        返回新MyPartialViewContext(wrapped.getPartialViewContext(上下文));
    }

}
 

MyPartialViewContext ,它提供了自定义的部分反应作家:

 公共类MyPartialViewContext扩展PartialViewContextWrapper {

    私人PartialViewContext包裹;
    私人PartialResponseWriter作家;

    公共MyPartialViewContext(PartialViewContext包裹){
        this.wrapped =包裹;
        this.writer =新MyPartialResponseWriter(wrapped.getPartialResponseWriter());
    }

    @覆盖
    公共PartialResponseWriter getPartialResponseWriter(){
        返回作家;
    }

    @覆盖
    公共无效setPartialRequest(布尔isPartialRequest){
        wrapped.setPartialRequest(isPartialRequest);
    }

    @覆盖
    公共PartialViewContext getWrapped(){
        返回包裹;
    }

}
 

MyPartialResponseWriter 这将写入&LT;扩展ID =myextension&GT; 用身体为JSON):

 公共类MyPartialResponseWriter扩展PartialResponseWriter {

    公共MyPartialResponseWriter(ResponseWriter包裹){
        超(包裹);
    }

    @覆盖
    公共无效调用endDocument()抛出IOException异常{
        startExtension(Collections.singletonMap(ID,myextension));
        写({\validationFailed \:+ FacesContext.getCurrentInstance()isValidationFailed()+}); //考虑一个JSON序列,如谷歌GSON。
        endExtension();
        super.endDocument();
    }

}
 

要让它运行,在如下注册工厂faces-config.xml中

 &LT;工厂&GT;
    <partial-view-context-factory>com.example.MyPartialViewContextFactory</partial-view-context-factory>
&LT; /工厂&GT;
 

下面是如何访问,分析和使用&LT;扩展ID =myextension&GT; jsf.ajax.addOnEvent( )

  jsf.ajax.addOnEvent(功能(数据){
    如果(data.status ==成功){
        变参= JSON.parse(data.responseXML.getElementById(myextension)firstChild.nodeValue。);

        如果(args.validationFailed){
            // ...
        }
        其他 {
            // ...
        }
    }
});
 


然而特定的功能性需求,可以在不同的,可能更简单,方式实现。只是让Ajax请求更新按钮本身,让按钮的禁用属性评估时,有一个成功的回传的方式

 &LT; H:的commandButton ID =myButton的值=做行动=#{testBacking.do}
    禁用=#{facesContext.postback而不是facesContext.validationFailed}&GT;
    &LT; F:AJAX执行=ID1渲染=@这个ID2监听器=#{testBacking.listener}/&GT;
&LT; / H:的commandButton&GT;
 

Consoder the following code:

<h:commandButton value="do" action="#{testBacking.do}">
   <f:ajax execute="@all" render="@all" listener="#{testBacking.listener}"/>
</h:commandButton>

I want to have a custom tag (with value based on server logic), in the Ajax response XML, something like the following:

<isValidationFailed> true </isValidationFailed>

I can use this data to re-enable the button (which was disabled when Ajax begin, to avoid double clicks) if validation is failed.

How can I achieve this (preferably without using any JSF 3rd party libraries)?

EDIT:

The example code, more precisely, should be like this:

<h:commandButton id="myButton" value="do" action="#{testBacking.do}">
 <f:ajax execute="id1" render="id2 myButton" listener="#{testBacking.listener}"/>
</h:commandButton>

解决方案

This is only possible with a custom PartialViewContext which you load into your JSF application using a PartialViewContextFactory. The custom PartialViewContext should in turn return a custom PartialResponseWriter on PartialViewContext#getResponseWriter(). In this custom PartialResponseWriter, you should be able to add extensions to the XML response by calling startExtension() and endExtension() in endDocument(). Something like:

@Override
public void endDocument() throws IOException {
    Map<String, String> attributes = new HashMap<String, String>();
    attributes.put("name1", "value1");
    attributes.put("name2", "value2");
    startExtension(attributes);
    write("lorem ipsum");
    endExtension();
    super.endDocument();
}

This will then end up in the XML response as

<extension name1="value1" name2="value2">lorem ipsum</extension>

This is available and traversable by data.responseXML in jsf.ajax.addOnEvent() function.


Here's a full kickoff example how you could utilize it in your particular case:

MyPartialViewContextFactory which provides the custom partial view context:

public class MyPartialViewContextFactory extends PartialViewContextFactory {

    private PartialViewContextFactory wrapped;

    public MyPartialViewContextFactory(PartialViewContextFactory wrapped) {
        this.wrapped = wrapped;
    }

    @Override
    public PartialViewContext getPartialViewContext(FacesContext context) {
        return new MyPartialViewContext(wrapped.getPartialViewContext(context));
    }

}

MyPartialViewContext which provides the custom partial response writer:

public class MyPartialViewContext extends PartialViewContextWrapper {

    private PartialViewContext wrapped;
    private PartialResponseWriter writer;

    public MyPartialViewContext(PartialViewContext wrapped) {
        this.wrapped = wrapped;
        this.writer = new MyPartialResponseWriter(wrapped.getPartialResponseWriter());
    }

    @Override
    public PartialResponseWriter getPartialResponseWriter() {
        return writer;
    }

    @Override
    public void setPartialRequest(boolean isPartialRequest) {
        wrapped.setPartialRequest(isPartialRequest);
    }

    @Override
    public PartialViewContext getWrapped() {
        return wrapped;
    }

}

MyPartialResponseWriter which writes <extension id="myextension"> with the body as JSON):

public class MyPartialResponseWriter extends PartialResponseWriter {

    public MyPartialResponseWriter(ResponseWriter wrapped) {
        super(wrapped);
    }

    @Override
    public void endDocument() throws IOException {
        startExtension(Collections.singletonMap("id", "myextension"));
        write("{\"validationFailed\": " + FacesContext.getCurrentInstance().isValidationFailed() + "}"); // Consider a JSON serializer, like Google Gson.
        endExtension();
        super.endDocument();
    }

}

To get it to run, register the factory as follows in faces-config.xml:

<factory>
    <partial-view-context-factory>com.example.MyPartialViewContextFactory</partial-view-context-factory>
</factory>

Here's how you can access, parse and use the <extension id="myextension"> in your jsf.ajax.addOnEvent():

jsf.ajax.addOnEvent(function(data) {
    if (data.status == "success") {
        var args = JSON.parse(data.responseXML.getElementById("myextension").firstChild.nodeValue);

        if (args.validationFailed) {
            // ...
        }
        else {
            // ...
        }
    }
});


However, your particular functional requirement can be achieved in a different, likely simpler, manner. Just let the ajax request update the button itself and let the button's disabled attribute evaluate true when there's means of a successful postback.

<h:commandButton id="myButton" value="do" action="#{testBacking.do}" 
    disabled="#{facesContext.postback and not facesContext.validationFailed}">
    <f:ajax execute="id1" render="@this id2" listener="#{testBacking.listener}"/>
</h:commandButton>

这篇关于在JSF Ajax响应XML插入自定义标签的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆