【发布时间】:2017-09-04 09:50:23
【问题描述】:
对于我的一个 JSF / primefaces 项目,我想显示自给定日期以来经过的时间 - 认为“此条目的最后编辑时间是 3 小时 5 分钟前”。
起初,我计算了支持 bean 中的时间间隔,并让视图轮询它。这意味着每秒一个 ajax 调用,而且很容易中断 - 不好。
所以我为这个任务制作了我的第一个简单的 JSF 复合组件。基本上它只是 h:outputText 的一个包装器:它将开始日期作为一个属性,然后在 Javascript 中它每秒计算到当前日期的时间间隔并相应地更新 outputText。
代码如下:
<?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:composite="http://java.sun.com/jsf/composite">
<composite:interface>
<composite:attribute name="start" />
</composite:interface>
<composite:implementation>
<div id="#{cc.clientId}" class="elapsedTime">
<h:outputText id="outTxt" value="#{cc.attrs.start}" />
</div>
<script type="text/javascript">
var outTxt = document.getElementById("#{cc.clientId}:outTxt");
var a = outTxt.innerHTML.split(/[^0-9]/);
var baseDate = new Date(a[0], a[1] - 1, a[2], a[3], a[4], a[5]);
function timeStringFromSeconds(s)
{
var hours = Math.floor((s / 86400) * 24);
var minutes = Math.floor(((s / 3600) % 1) * 60);
var seconds = Math.round(((s / 60) % 1) * 60);
if (minutes < 1) {
minutes = "00";
} else if (minutes < 10) {
minutes = "0" + minutes;
}
if (seconds < 1) {
seconds = "00";
} else if (seconds < 10) {
seconds = "0" + minutes;
}
return(hours + ":" + minutes + ":" + seconds);
}
function update() {
var currentDate = new Date();
var elapsed = (currentDate - baseDate) / 1000;
outTxt.innerHTML = timeStringFromSeconds(elapsed);
}
update();
setInterval(update, 1000);
</script>
</composite:implementation>
</html>
这是按预期工作的。但是,由于我无法直接从 JS 中检索 start 属性值,所以我让 h:outputText 先显示日期值,然后 JS 将从呈现的 HTML 中检索它并用经过的时间替换它。
因此,尽管我立即更新了值,但在某些浏览器/设备上,原始日期值是短暂可见的。整个事情对我来说就像一个丑陋的解决方法。如果出于某种原因我想使用第二个属性,我根本无法使用它,因此该方法显然受到限制/损坏。
所以我的问题是:有没有更简洁的方法来做到这一点,例如直接访问属性(如果可能的话)?
或者这只是你在复合材料中无法做到的事情?
非常感谢!
【问题讨论】:
-
首先,这与“复合”无关。其次,“但是,由于我无法直接从JS中检索start属性值”是什么意思,您的解决方案没有错,它是正常的。尝试找出“延迟”的来源。你知道这一点:timeago.yarp.com(无需自己构建)
-
@Kukeltje:谢谢!我的问题是通过属性将计算所基于的时间值带入组件中。因为我无法直接读取它的值,所以我将 outputText 组件绑定到属性,然后从 HTML 中选择值。与此同时,我发现您也可以在 Javascript 中使用 EL - 这是我想要的直接访问,请参阅我的答案。谢谢前段时间提,我去看看!最好的问候,烤面包机
标签: javascript jsf primefaces jsf-2