【问题标题】:JSF custom component, pass data from JSF to Javascript and reverseJSF 自定义组件,将数据从 JSF 传递到 Javascript 并反向
【发布时间】:2020-04-14 07:45:07
【问题描述】:

我想在 JSF 中构建一个自定义组件,它可以:

  1. 从其value 属性中检索一个值
  2. 显示此值
  3. 能够通过 Javascript 更新该值(将更新值组件属性中使用的 bean 属性)
<t:myComponent value="#{myBean.value}" />

会显示

<div>
    <input id="my_input" type="text" value="my_value" />
    <button onclick="update_value(document.getElementById('my_input').value)">update</button>
</div>

<script>
    function update_value(val) {
        // ???
    }
</script>

当我们点击按钮时,myBean.value 会被当前输入的内容改变(那个用户可以明显改变)。

据我了解,使用ResponseWriter 显示组件中的值看起来很容易,但我不明白如何构建 Javascript 来调用组件来更改组件的值。

例子

// myBean.value = "foo"

<t:myComponent value="#{myBean.value}" />

// displays

<div>
    <input id="my_input" type="text" value="foo" />
    <button ...>update</button>
</div>

// user change input content by "bar"

// user click the update button

// myBean.value = "bar" now

【问题讨论】:

  • 查看 PrimeFaces 组件(或带有 ajax 的 JSF 组件)的来源。他们都有这个。

标签: javascript jsf


【解决方案1】:

将 Bean 值传递给 Javascript

有一些方法可以做到这一点。我认为最明显的做法是渲染一个script 标签并将信息放入其中。

单值:

writer.write("var value = '" + yourValue + "';");

映射值:

String s = "var values = {";

for (Entry<String, String> entry : map.entrySet()) {
    s += entry.getKey() + ": '" + entry.getValue() + "',\n";
}

s = s.trim().substring(1, s.length() - 1); // removes last ','

s += "};";

writer.write(s);

列出值:

String s = "var values = [";

for (String value : list) {
    s += "'" + value + "', ";
}

s = s.trim().substring(1, s.length() - 1); // removes last ','

s += "];";

writer.write(s);

我建议不要在此脚本中添加任何内容,因为这将是encode 方法中的大量代码。而是将静态 javascript 代码放在 .js 文件中,然后将动态内容写入 script 标记。见how to get variables from other scripts


另一种方式不需要script 标签。这种方式会调用这样的js方法:

function init(values) {
    // ...
}

在渲染器中调用js方法即可:

facesContext.getPartialViewContext().getEvalScripts().add("init(" + yourValue + ");");

将 Javascript 值传递给服务器端

只需包含这样的输入:

// just a random unique id
String generatedId = context.getClientId(context) + ":utility";

// ...

writer.startElement("input", null);

writer.writeAttribute("id", generatedId, null);
writer.writeAttribute("name", generatedId, null);
writer.writeAttribute("type", "hidden", null);

writer.endElement("input");

然后将generatedId 与其他值一起传递给javascript。


在 Javascript 中:

function setValues(value) {
    // hiddenInputId is the server-side generatedId
    var input = document.getElementId(hiddenInputId);

    input.value = value;
}

然后只需发送一个 ajax 请求并获取 decode 方法中的值,如下所示:

// same id as in the encode methods
String generatedId = context.getClientId(context) + ":utility";

Map<String, String> map = facesContext.getExternalContext().getRequestParameterMap();

String value = map.get(generatedId);

// ...

【讨论】:

  • 我认为您错过了问题中最重要的部分:构建自定义组件...
  • @robinvrd 抱歉,我误读了问题并想到了复合组件。我将编辑答案以适合制作 UIComponent
  • @robinvrd 我已经编辑了问题以使其适合在自定义组件中使用
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-13
  • 2010-10-23
  • 1970-01-01
  • 2018-06-05
  • 2021-10-02
  • 2012-12-03
相关资源
最近更新 更多