无法从jQuery-tabs动态加载的选项卡中以另一种形式呈现元素

时间:2013-11-20 19:57:39

标签: ajax jsf jquery-tabs jsf-2.2

我有一个主页面,其中包含兴趣复合组件和延迟加载标签的链接,如下所示:

1-个人资料页:

<?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">
<ui:composition template="../templates/application.xhtml"
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:o="http://omnifaces.org/ui"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:myapp="http://java.sun.com/jsf/composite/component"
    xmlns:p="http://java.sun.com/jsf/passthrough">
        <ui:define name="head">
    <title>Profile</title>
    <script type="text/javascript" src="https://www.google.com/jsapi"></script>
    <link rel="stylesheet" type="text/css" href="#{request.contextPath}/resources/assets/css/jquery/jquery-ui.css" media="screen"/>
    <link rel="stylesheet" type="text/css" href="#{request.contextPath}/resources/assets/css/override-jquery.css" media="screen"/>
    <style>
        li
        {
            outline: none !important;
        }​
    </style>
    </ui:define>

<ui:define name="right-side">
    <div class="three-column right">          
    <myapp:interest bean="#{interestBean}" value="#{interestBean.interest}" id="interestCmp"></myapp:interest>              
    </div>
</ui:define>    
<ui:define name="content">
    <div class="tabs">
        <ul>
            <li><a id="tab1" href="tabs/tab1.xhtml">tab1</a></li>
            <li><a id="tab2" href="tabs/tab2.xhtml">tab2</a></li>
        </ul>
    </div>


<script type="text/javascript">head.ready(function(){$('.tabs').tabs();});</script>
</ui:define>
</ui:composition>

2-兴趣复合组件:

<?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:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"
    xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:composite="http://java.sun.com/jsf/composite">

<composite:interface>
    <composite:attribute name="id" />
    <composite:attribute name="index" />
    <composite:attribute name="value" />
    <composite:attribute name="bean" /> 
</composite:interface>

<composite:implementation xmlns:myapp="http://java.sun.com/jsf/composite/component">
<div >
<aside class="interests">
    <header class="header-w-flag icon-star">
        <h1>Interests</h1>
    </header>
    <h:form id="interestForm">
    <h:panelGroup id="showInterests" layout="block">
    <ui:repeat var="interest" value="#{interestBean.getUserInterests()}" >
        <div class="interest">
        <div class="interest-name"><a href="">#{interest.interestName}</a> 
        <h:commandLink  action="#{interestBean.deleteInterest(interest)}" rendered="#{permissionBean.isCurrentUser(profileBean.user)}" >
        <i class="icon-delete control-icon" style="cursor:pointer;display:none;"></i>
        <f:ajax render="@form" execute="@this"></f:ajax>
        </h:commandLink></div>
        <div class="people-grid"> 
        <ui:repeat var="user" value="#{interestBean.getUsersByInterest(interest.id)}" varStatus="status" >
        <h:panelGroup id="interestedUsers">
                            <a title="#{user.firstName} #{user.lastName}" href="../profile/index.xhtml?id=#{user.id}"><img src="#{applicationBean.avatarBaseURL}#{user.avatarUrl}" alt="#{user.firstName}" /></a>
        </h:panelGroup>
        </ui:repeat>
        </div>


       </div>
    </ui:repeat>
    </h:panelGroup>
   </h:form>
</aside>

        </div>
</composite:implementation>
</html>

3- tab1代码:

<?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:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:o="http://omnifaces.org/ui"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:myapp="http://java.sun.com/jsf/composite/component"
    xmlns:p="http://java.sun.com/jsf/passthrough">

   <div id="tab1">
            <!-- feed here -->
            <h:panelGroup layout="block" class="posts" id="feedContainer">
            <h:form id="profileFeeds">
            <ui:repeat var="post" value="#{feedBean.feeds}" varStatus="status" >
                <myapp:feedpost value="#{post}" index="{status.index}"></myapp:feedpost>    
            </ui:repeat>
            <h:panelGroup layout="block" rendered="#{feedBean.feeds.size()==0}">
                <div class="post blue">
                    <div class="post-content">

                        <h1>Nothing</h1>

                    </div>
                </div>
            </h:panelGroup>  

            <div class="post load"><h:commandLink action="#{feedBean.getMoreHomeFeeds()}" styleClass="btn btn-primary btn-small">Show more feeds
            <f:ajax render=":feedContainer" ></f:ajax>
            </h:commandLink></div>
            </h:form>
        </h:panelGroup>
    </div>



</html>

从tab1链接的4- feedpost复合组件:

<?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:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"
    xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:composite="http://java.sun.com/jsf/composite">

<composite:interface>
    <composite:attribute name="id" />
    <composite:attribute name="index" />
    <composite:attribute name="value" />

</composite:interface>

<composite:implementation xmlns:myapp="http://java.sun.com/jsf/composite/component">
    <h:panelGroup layout="block" class="post">
    <div class="post-content">      




                <h:panelGroup layout="block">
                        <h1><h:outputFormat value="#{cc.attrs.value.title}" /></h1>
                </h:panelGroup>

tText value="#{baseBean.replaceWithHTMLBreak(cc.attrs.value.note)}" escape="false"/></p>
                </h:panelGroup>


        </div>
    <myapp:comments value="#{cc.attrs.value}"></myapp:comments>
    </h:panelGroup> 
</composite:implementation>

</html>

5-评论从Feedpost组件链接的复合组件:

<?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:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"
    xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:composite="http://java.sun.com/jsf/composite">

<composite:interface>
    <composite:attribute name="id" />
    <composite:attribute name="index" />
    <composite:attribute name="value" />    
</composite:interface>

<composite:implementation>
        <h:panelGroup layout="block" class="comments" id="feedcomments">
        <div class="actions">

            <h:commandLink id="addToInterestLink" value="#{msg['action.addto.interests']}" styleClass="action-like"
                action="#{feedBean.addToInterests(cc.attrs.value)}">
                <f:ajax  execute="@this" render=":interestCmp:interestForm:showInterests"></f:ajax>
            </h:commandLink>

        </div>
    </h:panelGroup>
</composite:implementation>

</html>

当单击包含注释复合组件的tab1链接(延迟加载的jquery选项卡)时,该组件具有在兴趣组件中呈现兴趣div的链接,我得到以下异常:

<f:ajax> contains an unknown id ':interestCmp:interestForm:showInterests' - cannot locate it in the context of the component addToInterestLink

注意:我发现该问题的一个解决方法是将tab1内容​​静态添加到页面而不是链接它。

请告知如何解决这个问题。

1 个答案:

答案 0 :(得分:1)

好的,简而言之,有些简化(复合组件实际上不会在问题中发挥作用),你的问题就在这里:

profile.xhtml

<my:composite id="interestCmp"> <!-- Yes, invalid code; just to summarize. -->
    <h:form id="interestForm">
        <h:panelGroup id="showInterests">
            ...
        </h:panelGroup>
    </h:form>
</my:composite>
<div class="tabs">
    <ul>
        <li><a id="tab1" href="tabs/tab1.xhtml">tab1</a></li>
        <li><a id="tab2" href="tabs/tab2.xhtml">tab2</a></li>
    </ul>
</div>
<script>head.ready(function(){$('.tabs').tabs();});</script>

tab1.xhtml

中的某个地方
<h:form id="profileFeeds">
    <h:commandLink value="Add">
        <f:ajax render=":interestCmp:interestForm:showInterests" />
    </h:commandLink>
</h:form>

您正因此使用jQuery UI tabs来设置包含动态内容的标签式面板。但是,标签页tab1.xhtml不与主页profile.xhtml共享相同的JSF视图。它是物理上完全不同的视图。这完全解释了<f:ajax>无法在组件树(当前视图)中找到所需组件的原因。它只能看到tab1.xhtml本身包含的组件。它没有看到profile.xhtml的那些。它甚至看不到tab2.xhtml中的那些。

仅当您通过<ui:include>预加载标签而不是动态加载标签时,它才有效。这样,tab1.xhtml将在物理上与所需组件在同一视图中结束。假设您只需要为tab1.xhtml执行此操作,并且tab2.xhtml可以保持动态加载。这应该可以解决您的问题:

<div class="tabs">
    <ul>
        <li><a id="tab1" href="#tab1_page">tab1</a></li>
        <li><a id="tab2" href="tabs/tab2.xhtml">tab2</a></li>
    </ul>
    <div id="tab1_page">
        <ui:include src="tabs/tab1.xhtml" />
    </div>
</div>

您只需要分别用<?xml...?><!DOCTYPE ...><html xmlns...></html>替换tab1.xhtml的{​​{1}}和tab2.xhtml(实际上也是<ui:composition xmlns...>)。因为否则你最终会出现语法无效的HTML。

如果确实需要动态/延迟加载选项卡,那么您最好寻找能够胜任该工作的完整JSF组件,例如PrimeFaces <p:tabView>。更重要的是,PrimeFaces使用jQuery / UI作为look'n'feel,所以许多事情将与当前的方法非常相似。