动态创建链接

时间:2018-06-10 20:12:27

标签: jsf

我有一个用户定义的文本,例如

@SessionScoped
public class MyBean {
    private String text = "Life’s but a walking shadow, a poor player  
    that struts and frets his hour upon the stage and 
    then is heard no more.";

    public String getText() {
        return text;
    }
}

当然,文本不是静态的,而是从其他地方加载。我希望文本显示在页面中,如

<h:form id="myForm">
    <h:outputText value="#{myBean.text}" />
</h:form>

现在在bean中有一个标记某些单词的逻辑,例如每个名词,在文中。这些单词应该呈现为链接,就像它们是commandLinks一样。 也就是说,应该提交表单,我应该能够找到点击的链接。 类似的内容已经被问到hereherehere,但我不确定那里给出的解决方案是否适合我的情况。

我现在最好的猜测是将标记的单词中的文本拆分为bean中的片段列表,例如

List<TextSnippet> textSnippets;

class TextSnippet {
    private String precedingText;
    private String markedWord;
    ...
}

这样每个文本片段都以标记的单词结尾。然后我就可以遍历xhtml中的列表,例如

<h:form id="myForm">
    <ui:repeat var="snippet" value="#{myBean.textSnippets}">
        <h:outputText value="#{snippet.precedingText}" />
        <h:commandLink action="#{myBean.clickedOn(snippet.markedWord)}">
            <h:outputText value="#{snippet.markedWord}">
        </h:commandLink>
    </ui:repeat>
</h:form>

但是,我觉得这将bean(分裂的逻辑)紧密地耦合到视图中。有更好的想法吗?

2 个答案:

答案 0 :(得分:1)

我个人会做的是尝试保持jsf树的小,并实现类似下面的行,我认为更高效(disclamer:没有完整的代码来)

  • 在bean中准备文本服务器端This is a <div class="linkedWord">specific</div> word that needs a link and so is <div="linkedWord">this</div>
  • 通过<h:outputText value="#{myBean.text}">(用于转义!)
  • 以纯HTML格式输出
  • class="linkedWord"上添加jquery动态事件处理程序(因此它适用于每个链接)并调用javascript函数
  • 在javascript函数中读取div的内容(或者可以将文本添加为​​data-属性(如<div class="linkedWord" data-word="specific">specific</div>
  • 并为之前的JSF版本(或`p:remoteCommand)调用<h:commandScript>(JSF 2.3及更高版本)或o:commandScript并传递div的内容(或属性的值) )作为服务器端方法的参数。

请注意,没有明确的理由在&#39; JSF&#39;中做一切。办法。使用客户端功能和与JSF的一些小型集成是非常有效的用法。不这样做的人经常会责怪他们。 JSF,但它们本身实际上是导致行为不太理想的原因)

另见:

答案 1 :(得分:0)

你似乎采取了正确的方式,但我认为我可以建议你做一些改进。不知道您的确切要求,但您当前的结构限制了标记的单词(我猜这只是一个链接)在段落的末尾。如果你之后有文字会怎么样?有两个标记的话怎么样?这个类可能更适合:

class TextSnippet {
    private String text;
    private String linkUrl;
    ...
}

您需要按照自己的方式构建List<TextSnippet>,但之前会评估这些链接,因此ui:repeat可以访问它们。

然后,迭代它。您已经获得了POST,而不是执行POST来评估去向,所以如果您想要指向应用程序中的某个位置,则可以使用h:link,如果是{39},则可以使用h:outputLink在它之外:

<ui:repeat var="snippet" value="#{myBean.textSnippets}">
    <h:outputText value="#{snippet.text}" rendered="#{empty snippet.linkUrl}" />
    <h:link outcome="#{snippet.linkUrl}" rendered="#{not empty snippet.linkUrl}">
        <h:outputText value="#{snippet.text}">
    </h:link>
</ui:repeat>