为了避免用户在同一个按钮上重复点击并使用相同的令牌向服务器发送多个请求,我使用了以下模式:
请参阅下面的代码中的模式。下面的“rpcCall”函数基本上是Button onClick(最终的ClickEvent事件)的核心实现。
private void rpcCall(final ClickEvent event)
{
final AsyncCallback<Void> callback = new AsyncCallback<Void>()
{
@Override
public void onSuccess(Void result)
{
final Button source = (Button) event.getSource(); // Dev mode isLive assertion failure.
source.setEnabled(true);
// Process success...
}
@Override
public void onFailure(Throwable caught)
{
final Button source = (Button) event.getSource();
source.setEnabled(true);
// Process error...
}
};
// Disable sender.
final Button source = (Button) event.getSource();
source.setEnabled(false);
// RPC call.
final RpcAsync rpcAsync = getRpcAsync();
RpcAsync.rpcCall(..., callback);
}
我刚注意到“当事件处理器管理器已经完成了这个事件的处理,所以你不能再访问它了”当onSuccess异步函数调用event.getSource()时,dev模式下的isLive断言失败导致异常
它似乎在生产/ javascript模式下工作。
这种开发模式断言失败让我质疑这种模式。
这是一个好模式吗?为什么我只在开发模式下获得异常?什么是更好的模式?
显然,我可以通过将源Button作为rpc包装器调用函数的参数传递来绕过对event.getSource()的调用,但是对于已经带有这样的引用的事件对象来说它似乎是多余的。
答案 0 :(得分:2)
从历史上看,你在IE中获取事件对象的方式是使用window.event
,这只是持续时间来处理事件。因此,GWT的Event
对象必须放置警卫,因此您不鼓励保留事件实例,因为它可能突然反映正在处理的另一个事件,或者根本没有事件(很奇怪!)
幸运的是,微软已经修复了他们的浏览器,这就是为什么它在你测试时有效(我打赌你没有在IE6中测试;-))。
处理这种情况的正确的方法是从事件中提取所需的所有数据,并将它们保存在final
个变量中:
private void rpcCall(final ClickEvent event)
{
final Button source = (Button) event.getSource();
final AsyncCallback<Void> callback = new AsyncCallback<Void>()
{
@Override
public void onSuccess(Void result)
{
source.setEnabled(true);
// Process success...
}
@Override
public void onFailure(Throwable caught)
{
source.setEnabled(true);
// Process error...
}
};
// Disable sender.
source.setEnabled(false);
// RPC call.
final RpcAsync rpcAsync = getRpcAsync();
RpcAsync.rpcCall(..., callback);
}