这个问题是针对accordionPanel的,但我相信它可以被问到类似dataGrid的动态渲染器。
我想在手风琴每个标签中的画布上画画。类似于这个jsfiddle示例。
根据此面板:
<form id="someForm">
<p:accordionPanel id="accordion" value="#{dataModel.values}" var="value">
<p:tab id="entry" title="Entry - #{value}">
<div id="layout">
<canvas id="canvas" width="300" height="200">
</canvas>
<div id="foo" class="foo">#{value.data1}</div>
<div id="bar" class="bar">#{value.data2}</div>
</div>
</p:tab>
</p:accordionPanel>
<p:remoteCommand name="updateAccordion" update="accordion"/>
</form>
当html被渲染时,foo和bar获得类似于:someForm:entry:0:foo
、:someForm:entry:1:foo
等的ID。我如何通过javascript以编程方式访问这些元素,正如我在jsfiddle中所展示的那样?
如果有一条你认为更适合我的替代道路,我绝对愿意尝试
以下是我读过的其他一些问题,但还没有得到足够的信息来帮助:
如何在update="@(.myClass)"中使用PrimeFaces选择器?
如何找到ajax更新/渲染组件的客户端ID?找不到从"bar"引用的表达式为"foo"的组件
最后一个链接似乎有最好的细节,但它似乎只是不可能做我想做的事情。
非常感谢你的帮助,我期待着获得一些新的知识。
谢谢。
更新:
我能够想出一个解决方案,并想与其他最终处于类似情况的人分享,但首先我想添加一些更多细节。
现在重读我的问题,我想我遗漏了一些关于acordionPanel是如何更新的细节。支持bean维护每个选项卡中显示的内容的状态,当bean更新时,它会通过web套接字通知客户端状态已更改。在这个通知中,除了远程命令将更新的内容之外,我还需要在每个选项卡上绘制一些信息。在处理来自websocket的消息时,它将调用上面的远程命令来更新accordionPanel。
正如更新中承诺的那样,这就是我解决问题的方法。
我的主要问题是,我需要能够关联传递到web套接字的JSON数据,告诉手风琴进行更新。JSON数据包含一个键,但HTML本身没有键。为此,我在div .layout
中添加了一个data-key
属性。有了这个属性,我现在可以将每个手风琴选项卡与JSON数据关联起来。我还在手风琴上定义了widgetVar,这样我就可以更好地处理选项卡。
<form id="someForm">
<p:accordionPanel id="accordion" value="#{dataModel.values}" var="value" widgetVar="accordion">
<p:tab id="entry" title="Entry - #{value.title}">
<div class="layout" data-key="#{value.key}">
<canvas id="canvas" width="300" height="200">
</canvas>
<p:outputPanel id="foo" styleClass="foo">#{value.data1}</p:outputPanel>
<p:outputPanel id="bar" styleClass="bar">#{value.data2}</p:outputPanel>
</div>
</p:tab>
</p:accordionPanel>
<p:remoteCommand name="updateAccordion" update="accordion" oncomplete="processUpdate()"/>
</form>
当JSON从web套接字中出来后进行处理时,我保存了数据,以便在ajax调用完成后processUpdate()
可以引用它。
这使得processUpdate()
看起来像这样:
// JSON data from original update message
var canvasData = ...;
function drawLine() {
// ...
}
function processUpdate() {
var tabs = PF('accordion').panels;
for (var i = 0; i < tabs.length; i++) {
var tab = $(tabs[i]);
var key = tab.find('.layout').attr('data-key');
for (var j = 0; j < canvasData.length; j++) {
// Find the data that matches key
if (canvasData[j].key == key) {
var data = canvasData[jj];
break;
}
}
var canvas = $('#canvas');
// With a handle on the tab, I could now ignore the `someForm:entry:1:`
// prefix that made the element unique as I am now in the context of
// one tab.
var foo = tab.find('[id$=foo]');
var bar = tab.find('[id$=bar]');
drawLine(canvas, data, foo, bar);
}
}
@Kukeltje-谢谢你帮我解决问题。