用于减少耦合和网络流量的JSF客户端事件框架

时间:2016-10-14 08:25:28

标签: javascript jsf-2.2 omnifaces

网页包含'静态' 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代码将由服务器重新呈现。但是,这并不高效,因为我们实际上并不需要更新整个组件,而只需更新它(可能很小)。

我用这种方法可以看到的第二个问题是按钮和复合组件之间的耦合。在这个简单的例子中,它可能不是一个真正的问题。但是在更复杂的网页中,可能不需要这种耦合,因为它可能会导致更多的维护成本。

我没有找到任何框架来做到这一点。所以我实施了一个。如果你知道这样的框架,请告诉我!

1 个答案:

答案 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%。

当然,这种方法可能存在一些我不会看到的缺点。在这种情况下,请随时回复,并给我建议。谢谢:))