我有以下问题: 我正在尝试使用GWT对流程进行建模,其中我有一些带有几个提交按钮的视图。按下button1将创建服务器交互,如果一切正常,将加载下一个视图。我的问题是,现在我得到了非常讨厌的意大利面条代码(只是非常高级以向您展示我的意思):
onClick {
AsyncCallback {
onSuccess {
load new view with another clickhandler and an asynccallback
}
}
}
有没有办法创建某种抽象或什么?也许是国家模式?怎么样?非常感谢!
答案 0 :(得分:6)
这实际上是一个非常好的问题 - 可能是一个没有确定答案的问题。这是一个适用于许多框架的问题,而不仅仅是GWT,所以我喜欢你的想法,用一些简化的代码来看待它。我会让它更长一点,以显示即使只有4个非常简单的回调看起来像:
alice.call("a", new Callback() {
@Override
public void onSuccess() {
bob.call("b", new Callback() {
@Override
public void onSuccess() {
charlie.call("c", new Callback() {
@Override
public void onSuccess() {
daisy.call("d", new Callback() {
@Override
public void onSuccess() {
// finished
}
});
}
});
}
});
}
});
您可以使用IDE轻松地将其重构为命名回调(提示:请从下到上阅读回调!):
final Callback daisyCallback = new Callback() {
@Override
public void onSuccess() {
// finished
}
};
final Callback charlieCallback = new Callback() {
@Override
public void onSuccess() {
daisy.call("d", daisyCallback);
}
};
final Callback bobCallback = new Callback() {
@Override
public void onSuccess() {
charlie.call("c", charlieCallback);
}
};
final Callback aliceCallback = new Callback() {
@Override
public void onSuccess() {
bob.call("b", bobCallback);
}
};
alice.call("a", aliceCallback);
这是与事件总线相同的调用方式:
alice.call("a", new Callback() {
@Override
public void onSuccess() {
bus.fireEvent(BusEvent.ALICE_SUCCESSFUL_EVENT);
}
});
bus.addEventListener(BusEvent.ALICE_SUCCESSFUL_EVENT, new BusEventListener() {
@Override
public void onEvent(final BusEvent busEvent) {
bob.call("b", new Callback() {
@Override
public void onSuccess() {
bus.fireEvent(BusEvent.BOB_SUCCESSFUL_EVENT);
}
});
}
});
bus.addEventListener(BusEvent.BOB_SUCCESSFUL_EVENT, new BusEventListener() {
@Override
public void onEvent(final BusEvent busEvent) {
charlie.call("c", new Callback() {
@Override
public void onSuccess() {
bus.fireEvent(BusEvent.CHARLIE_SUCCESSFUL_EVENT);
}
});
}
});
bus.addEventListener(BusEvent.CHARLIE_SUCCESSFUL_EVENT, new BusEventListener() {
@Override
public void onEvent(final BusEvent busEvent) {
daisy.call("d", new Callback() {
@Override
public void onSuccess() {
bus.fireEvent(BusEvent.DAISY_SUCCESSFUL_EVENT);
}
});
}
});
bus.addEventListener(BusEvent.DAISY_SUCCESSFUL_EVENT, new BusEventListener() {
@Override
public void onEvent(final BusEvent busEvent) {
// finished
}
});
根据我的经验,通过混合嵌套和命名回调来“划分和征服”通常是一个好主意:
final Callback charlieCallback = new Callback() {
@Override
public void onSuccess() {
daisy.call("d", new Callback() {
@Override
public void onSuccess() {
// finished
}
});
}
};
alice.call("a", new Callback() {
@Override
public void onSuccess() {
bob.call("b", new Callback() {
@Override
public void onSuccess() {
charlie.call("c", charlieCallback);
}
});
}
});
根据具体情况,两个嵌套回调通常仍然可读,并且当读取代码50%时,它们会减少方法之间的跳跃。
(我在这里创建了一个我的示例的pastebin,如果你想玩它们:http://pastebin.com/yNc9Cqtb)
答案 1 :(得分:1)
Spaghetti代码在GWT中是一个棘手的问题,因为它在Javascript中,其中大部分代码都是围绕异步回调构建的。
this question的答案中描述的一些处理它的技术可能适用。
答案 2 :(得分:0)
避免小部件之间耦合的建议方法是使用EventBus。在此处阅读更多详情https://developers.google.com/web-toolkit/articles/mvp-architecture#events
希望它有所帮助。
答案 3 :(得分:0)
从一开始就使用MVP。使用活动和地点。你的代码很干净。
答案 4 :(得分:0)
changeview(boolean first){
if(first)
{
firstView.setVisible(true);
secondView.setVisible(false);
}else{
firstView.setVisible(false);
secondView.setVisible(true);
}
}
onClick {
AsyncCallback {
onSuccess {
changeView(false);
}
}
}
按上述方式切换视图。