网页包含'静态' HTML元素(它们永远不会更新)和动态'元素,由一些JavaScript代码更新。在像JSF这样的服务器端技术中,让服务器重新生成整个HTML元素块(在AJAX请求上)非常简单方便,而这几乎不需要额外的工作就可以完成(这是一个我之所以如此欣赏JSF的原因,有时这种技术在网络流量和服务器负载方面效率不高。
让我们举一个例子,我们有一个复合组件和一个使用页面。
复合组件如下:
<cc:implementation>
<div id="#{cc.clientId}">
<div>
<!-- block of HTML elements that don't have to be updated -->
</div>
<div jsf:id="some-part">
<!-- block of HTML elements that we would like to update -->
</div>
</div>
</cc:implementation>
使用页面:
<h:form>
<h:commandButton value="Press me">
<f:ajax event="click" listener="#{bean.someListener()}" render="component"/>
</h:commandButton>
</h:form>
<!-- somewhere else in the page -->
<my:component id="component"/>
按下该按钮时,将发生部分更新,其中复合组件的HTML代码将由服务器重新呈现。但是,这并不高效,因为我们实际上并不需要更新整个组件,而只需更新它(可能很小)。
我用这种方法可以看到的第二个问题是按钮和复合组件之间的耦合。在这个简单的例子中,它可能不是一个真正的问题。但是在更复杂的网页中,可能不需要这种耦合,因为它可能会导致更多的维护成本。
我没有找到任何框架来做到这一点。所以我实施了一个。如果你知道这样的框架,请告诉我!
答案 0 :(得分:1)
复合组件更改为:
<cc:implementation>
<div id="#{cc.clientId}">
<div>
<!-- block of HTML elements that don't have to be updated -->
</div>
<div jsf:id="some-part">
<!-- block of HTML elements that we would like to update -->
</div>
<!-- add an event observer that will only update the needed parts -->
<h:form>
<steappe:eventObserver event="some-semantic-event"
listener="#{beans.someListener()}"
render=":#{cc.clientId}:some-part"/>
</h:form>
</div>
</cc:implementation>
使用页面改为:
<!-- add an event producer that reacts on the button click - no form needed here -->
<h:commandButton value="Press me">
<steappe:eventProducer on="click" event="some-semantic-event"/>
</h:commandButton>
<!-- somewhere else in the page -->
<my:component id="component"/>
按钮和组件之间没有耦合。该按钮只会触发一个语义事件,并不关心此事件会发生什么。
复合组件会观察语义事件,当触发此类事件时,它仅更新需要更新的部分。
此事件框架也可以与Web套接字(我使用Onmifaces)一起使用,以便自动更新网页。
<o:socket channel="some-channel" onmessage="steppe.eventing.dispatchSocketMessage"/>
<!-- somewhere else in the page -->
<my:component id="component"/>
当服务器通过Web Socket向客户端发送消息时,如果此消息是原始字符串,则此消息被视为事件并被分派给所有观察者。
<强>实施强>
实施仍在BETA中,可在github上的以下地址获得:https://github.com/steappe/jsf-eventing
我已经在基于当前生产的代码的测试环境中测试了这种方法,并且在某些情况下它可以将网络流量减少多达70%。
当然,这种方法可能存在一些我不会看到的缺点。在这种情况下,请随时回复,并给我建议。谢谢:))