gpt4 book ai didi

javascript - p :calendar trigger javascript method after first view is rendered

转载 作者:行者123 更新时间:2023-12-01 00:44:23 26 4
gpt4 key购买 nike

我想创建一个复合 Material 来增强 <p:calendar> 。这就是我所拥有的:

calendar.xhtml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:composite="http://java.sun.com/jsf/composite">

<composite:interface>
<composite:attribute name="bean" />
</composite:interface>

<composite:implementation>
<h:form id="calendarForm" class="calendarForm" >
<h:outputScript library="js" name="calendar.js" />
<p:inputText type="hidden" id="dateInfoMap" class="dateInfoMap" value="#{cc.attrs.bean.dateInfoMap}"/>

<p:calendar
id="calendar"
value="#{cc.attrs.bean.selectedDate}"
mode="inline" >
<p:ajax event="viewChange" listener="#{cc.attrs.bean.makeDateInfoMapForMonth}" update="dateInfoMap" oncomplete="alterCalendar(this)" />
</p:calendar>

</h:form>
</composite:implementation>
</html>

函数cc.attrs.bean.makeDateInfoMapForMonth创建一个对象,其中包含有关当月每一天的信息(可从 viewChange 事件获取)并将其存储在 cc.attrs.bean.dateInfoMap 中.

calendar.js

function alterCalendar(ajaxRequest) {
let calendar = document.getElementById(ajaxRequest.source);
let dateInfoMap = getDateInfoMap(calendar);
// do stuff with this calendar and dateInfoMap
}

function getDateInfoMap(calendar) {
return JSON.parse($(calendar).closest(".calendarForm").find(".dateInfoMap")[0].value);
}

所有这些都按预期工作:当我更改月份时,新月份会显示 alterCalendar() 中所做的所有更改。使用 dateInfoMap 中的正确信息.

但是,这是在我第一次更改月份之后才完成的。 <p:calendar>第一次渲染后似乎没有触发事件。我怎样才能有alterCalendar()此时适用吗?

两种可能的解决方案似乎都不适合这样的组件:

  1. 如果存在触发日历渲染的 ajax,我可以告诉组件的用户调用 javascript 函数作为 oncomplete 回调。这 a) 对用户来说不太好,b) 并不总是适用,c) 如果不手动输入组件 ID,则很难动态获取日历实例。

  2. 我可以使用类似 $(document).ready() 的表达式,但是如果日历的渲染确实是由另一个 ajax 触发的,这可能不起作用,并且 1 c) 也适用于此。

是否有另一种更优雅的方式可以动态获取日历的实例或 ID?

编辑:我尝试使用 beforeShow <p:calendar> 的属性,但它没有做任何事情。我正在使用 Primefaces 6.2

最佳答案

kukeltje的帮助下,我可以解决这个问题并消除其他问题。

1) key 是#{cc.clientId} 。这在复合命名空间中可用,并为我提供了 Javascript 所需的组件 ID。

2) 表单不应该是组合的一部分。 See here for more info.

3) 我可以使用#{...} xhmtl 页面上 Javascript 中的任何位置。

4) 我不需要隐藏的输入字段,我可以使用 RequestContext将值传递给 Javascript 函数。如果我使用#{cc.attrs.bean.dateInfoMap} ,该值并不总是最新的,因为它是用 <p:ajax> 呈现的。 See here for more info.

这引导我找到这个解决方案:

calendar.xhtml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:composite="http://java.sun.com/jsf/composite">

<composite:interface>
<composite:attribute name="bean" />
</composite:interface>

<composite:implementation>
<h:outputScript library="js" name="calendar.js" />
<p:calendar
id="calendar"
value="#{cc.attrs.bean.selectedDate}"
mode="inline" >
<p:ajax
event="viewChange"
listener="#{cc.attrs.bean.makeDateInfoMapForMonth}"
oncomplete="alterCalendar('#{cc.clientId}', args.dateInfoMap)" />
</p:calendar>
<script>
alterCalendar('#{cc.clientId}', '#{cc.attrs.bean.dateInfoMap}');
</script>
</composite:implementation>
</html>

在 bean 中:

public void makeDateInfoMapForMonth(DateViewChangeEvent event) {
dateInfoMap = //...
RequestContext.getCurrentInstance().addCallbackParam("dateInfoMap", dateInfoMap);
}

calendar.js

function alterCalendar(componentClientId, dateInfoMap) {
let calendar = document.getElementById(componentClientId + ":calendar");
dateInfoMap = JSON.parse(dateInfoMap);
$(calendar).ready(function () {
// do stuff
});
});
}

关于javascript - p :calendar trigger javascript method after first view is rendered,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57509222/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com