如何用异步回调实现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 摘自评论部分)。