如何用异步回调实现MVC?
How to implement MVC with asynchronous callbacks?
我目前正在重构我的 GWT 客户端,并尝试将 MVC 模式应用到所有相关方面 类。我的问题是我不确定这里有两件事:
- 我在哪里可以控制显示哪个视图?例如,如果用户登录并且应该加载起始页。控制器会加载该页面或模型吗?
- 我如何最好地处理异步回调以及谁(模型或控制器)应该持有异步服务?
我有这个简单的登录示例,它是我当前的实际代码:
登录模型
// LoginModel appears kind of obsolete ..
public class LoginModel {
private final LoginServiceAsync loginService = LoginService.Util.getInstance();
public void onLoginClick(String userId, String password, AsyncCallback<UserDTO> asyncCallback) {
// Login on the server ..
this.loginService.login(userId, password, asyncCallback);
}
}
LoginView
public class LoginView extends Composite {
private static UILoginUiBinder uiBinder = GWT.create(UILoginUiBinder.class);
@UiField Button btnLogin;
@UiField TextBox txtPassword;
@UiField TextBox txtUserID;
interface UILoginUiBinder extends UiBinder<Widget, LoginView> {
}
public LoginView() {
initWidget(uiBinder.createAndBindUi(this));
}
public void addLoginButtonClickHandler(ClickHandler clickHandler) {
this.btnLogin.addClickHandler(clickHandler);
}
public String getUserId() {
return this.txtUserID.getText();
}
public String getPassword() {
return this.txtPassword.getText();
}
public void displayLoginFailure() {
// TODO display login failure ..
}
}
登录控制器
public class LoginController {
private final LoginModel loginModel;
private final LoginView loginView;
public LoginController(LoginModel loginModel, final LoginView loginView) {
this.loginModel = loginModel;
this.loginView = loginView;
this.loginView.addLoginButtonClickHandler(new LoginButtonClickHandler());
}
private class LoginButtonClickHandler implements ClickHandler {
@Override
public void onClick(ClickEvent event) {
loginModel.onLoginClick(loginView.getUserId(), loginView.getPassword(), new AsyncCallback<UserDTO>() {
public void onFailure(Throwable caught) {
onLoginFailure(caught);
}
public void onSuccess(UserDTO userDto) {
onLoginSuccess(userDto);
}
});
}
}
public void onLoginFailure(Throwable caught) {
Throwable cause = caught.getCause();
if (cause instanceof LoginException) {
GWT.log("Cause: " + cause.getMessage());
cause.printStackTrace();
}
this.loginView.displayLoginFailure();
}
public void onLoginSuccess(UserDTO userDto) {
// NOTE: UIStart is what is going to become StartView!
UIStart home = new UIStart();
RootPanel.get("mainUIContainer").clear();
RootPanel.get("mainUIContainer").add(home);
}
}
这是 MVC 模式的一个很好的实现吗?我可以做得更好吗?
模型-视图-控制器 (MVC) 是一种用于实现用户界面的软件架构模式。它将给定的软件应用程序分为三个相互关联的部分,以便将信息的内部表示与向用户呈现或接受信息的方式分开(来源:Wikipedia)
也就是说,MVC 有 3 个组件,
1) 模型:理想情况下,它应该只包含 getter 和 setter。这里不应该提到商业逻辑
2) 视图:这部分只包含视图。您不会 link 您对此处主要 html 的看法。它只是一个可以访问模型的简单视图。
3) Controller:您所有的业务逻辑都应该放在这里。控制器可以访问视图和模型。
MVC w.r.t GWT 应该是这样的。
第一个控制器被实例化。然后控制器创建模型和视图的实例。
模型与视图一起 link 编辑,通常模型作为参数传递给视图。您可以像 angular 一样使用命令模式实现双重绑定,并根据需要更改侦听器或更新模型值(通常在保存或提交时)
现在进入异步部分。所有异步处理都应该在控制器上完成。在控制器中,异步调用成功后,模型应该被更新,它又会更新视图,因为模型 link 与视图一起编辑。
我希望这能回答您的问题并向您解释 MVC 范例。
Ray Ryan 在 Google I/O 2009 年的演讲中:Best Practices for Architecting GWT App
在 GWT 中,您不使用 MVC,而是使用 MVP(模型 - 视图 - 演示器),它可以更清晰地划分各个部分。您可以将 MVP 用于您的小部件和屏幕。
接下来使用 EventBus 来解耦组件。
最后您应该使用 Activities & Places 在您的应用程序中导航。
看看这里:
MVP Activities and Places。
这是一个很好的起点。
此外,您可以查看 GWT 平台 GWTP or mvp4g,因为它们是 GWT 中 mvp 模式的不同实现。
正如 Abhijith Nagaraja 已经提到的:在演示者内部进行异步调用。
编辑: 另见 Demystifying MVP and EventBus in GWT(Link 摘自评论部分)。
我目前正在重构我的 GWT 客户端,并尝试将 MVC 模式应用到所有相关方面 类。我的问题是我不确定这里有两件事:
- 我在哪里可以控制显示哪个视图?例如,如果用户登录并且应该加载起始页。控制器会加载该页面或模型吗?
- 我如何最好地处理异步回调以及谁(模型或控制器)应该持有异步服务?
我有这个简单的登录示例,它是我当前的实际代码:
登录模型
// LoginModel appears kind of obsolete ..
public class LoginModel {
private final LoginServiceAsync loginService = LoginService.Util.getInstance();
public void onLoginClick(String userId, String password, AsyncCallback<UserDTO> asyncCallback) {
// Login on the server ..
this.loginService.login(userId, password, asyncCallback);
}
}
LoginView
public class LoginView extends Composite {
private static UILoginUiBinder uiBinder = GWT.create(UILoginUiBinder.class);
@UiField Button btnLogin;
@UiField TextBox txtPassword;
@UiField TextBox txtUserID;
interface UILoginUiBinder extends UiBinder<Widget, LoginView> {
}
public LoginView() {
initWidget(uiBinder.createAndBindUi(this));
}
public void addLoginButtonClickHandler(ClickHandler clickHandler) {
this.btnLogin.addClickHandler(clickHandler);
}
public String getUserId() {
return this.txtUserID.getText();
}
public String getPassword() {
return this.txtPassword.getText();
}
public void displayLoginFailure() {
// TODO display login failure ..
}
}
登录控制器
public class LoginController {
private final LoginModel loginModel;
private final LoginView loginView;
public LoginController(LoginModel loginModel, final LoginView loginView) {
this.loginModel = loginModel;
this.loginView = loginView;
this.loginView.addLoginButtonClickHandler(new LoginButtonClickHandler());
}
private class LoginButtonClickHandler implements ClickHandler {
@Override
public void onClick(ClickEvent event) {
loginModel.onLoginClick(loginView.getUserId(), loginView.getPassword(), new AsyncCallback<UserDTO>() {
public void onFailure(Throwable caught) {
onLoginFailure(caught);
}
public void onSuccess(UserDTO userDto) {
onLoginSuccess(userDto);
}
});
}
}
public void onLoginFailure(Throwable caught) {
Throwable cause = caught.getCause();
if (cause instanceof LoginException) {
GWT.log("Cause: " + cause.getMessage());
cause.printStackTrace();
}
this.loginView.displayLoginFailure();
}
public void onLoginSuccess(UserDTO userDto) {
// NOTE: UIStart is what is going to become StartView!
UIStart home = new UIStart();
RootPanel.get("mainUIContainer").clear();
RootPanel.get("mainUIContainer").add(home);
}
}
这是 MVC 模式的一个很好的实现吗?我可以做得更好吗?
模型-视图-控制器 (MVC) 是一种用于实现用户界面的软件架构模式。它将给定的软件应用程序分为三个相互关联的部分,以便将信息的内部表示与向用户呈现或接受信息的方式分开(来源:Wikipedia)
也就是说,MVC 有 3 个组件,
1) 模型:理想情况下,它应该只包含 getter 和 setter。这里不应该提到商业逻辑
2) 视图:这部分只包含视图。您不会 link 您对此处主要 html 的看法。它只是一个可以访问模型的简单视图。
3) Controller:您所有的业务逻辑都应该放在这里。控制器可以访问视图和模型。
MVC w.r.t GWT 应该是这样的。
第一个控制器被实例化。然后控制器创建模型和视图的实例。
模型与视图一起 link 编辑,通常模型作为参数传递给视图。您可以像 angular 一样使用命令模式实现双重绑定,并根据需要更改侦听器或更新模型值(通常在保存或提交时)
现在进入异步部分。所有异步处理都应该在控制器上完成。在控制器中,异步调用成功后,模型应该被更新,它又会更新视图,因为模型 link 与视图一起编辑。
我希望这能回答您的问题并向您解释 MVC 范例。
Ray Ryan 在 Google I/O 2009 年的演讲中:Best Practices for Architecting GWT App
在 GWT 中,您不使用 MVC,而是使用 MVP(模型 - 视图 - 演示器),它可以更清晰地划分各个部分。您可以将 MVP 用于您的小部件和屏幕。 接下来使用 EventBus 来解耦组件。
最后您应该使用 Activities & Places 在您的应用程序中导航。
看看这里: MVP Activities and Places。 这是一个很好的起点。
此外,您可以查看 GWT 平台 GWTP or mvp4g,因为它们是 GWT 中 mvp 模式的不同实现。
正如 Abhijith Nagaraja 已经提到的:在演示者内部进行异步调用。
编辑: 另见 Demystifying MVP and EventBus in GWT(Link 摘自评论部分)。