我正在尝试使用Dagger2创建子结构,并且eveything工作正常。
我的主要问题是在我需要在模型文件中调用presenter方法时启动。让我详细介绍一下。
正如您在我的模型文件中所见,我向服务器请求改造,并根据结果我应该从演示者调用一个方法。因为Model将决定在演示者中应该使用哪种方法,并且根据选择的方法,演示者将调用视图方法。但问题是Presenter通过调用Constructor来使用Model,但即使Presenter是中间人,Model也不能使用Presenter。
这是我的MVP接口集群。
public interface IRegisterMVP {
interface View extends IGeneralViewOps{
void showWarning( String warningMessage );
void openMainActivity();
}
interface Presenter {
void setView( View view );
void registerTriggered( ArrayMap< String, String > userParameters );
void registerTriggered( EditText userName, EditText mailAddress, EditText password, EditText passwordRepeat );
void notValidated( String warningMessage );
void validate();
}
interface Model {
void validateData( ArrayMap< String, String > userParameters );
}
这是我的模块
@Module
public class UserOperationsModule {
@Provides
public IRegisterMVP.Presenter provideRegisterPresenter( IRegisterMVP.Model model ){
return new RegisterFragmentPresenter( model );
}
@Provides
public IRegisterMVP.Model provideRegisterModel( Context context, IRegisterMVP.Presenter presenter ){
return new UserBussinessModel( context );
}
}
这是我的演讲者
public class RegisterFragmentPresenter implements IRegisterMVP.Presenter {
private IRegisterMVP.View mView;
private IRegisterMVP.Model mModel;
public RegisterFragmentPresenter( IRegisterMVP.Model mModel ) {
this.mModel = mModel;
}
@Override
public void setView( IRegisterMVP.View view ) {
this.mView = view;
}
@Override
public void registerTriggered( ArrayMap< String, String > userParameters ) {
this.mModel.validateData( userParameters );
}
@Override
public void registerTriggered( EditText userName, EditText mailAddress, EditText password, EditText passwordRepeat ) {
ArrayMap< String, String > createViewValues = new ArrayMap<>( 4 );
createViewValues.put( UserBussinessModel.USER_NAME, userName.getText().toString() );
createViewValues.put( UserBussinessModel.USER_MAIL_ADDRES, mailAddress.getText().toString() );
createViewValues.put( UserBussinessModel.USER_PASS, password.getText().toString() );
createViewValues.put( UserBussinessModel.USER_PASS_REPEAT, passwordRepeat.getText().toString() );
this.registerTriggered( createViewValues );
}
@Override
public void notValidated( String warningMessage ) {
this.mView.hideWaitingView();
this.mView.showWarning( warningMessage );
}
@Override
public void validate() {
this.mView.hideWaitingView();
this.mView.openMainActivity();
}
}
这是我的businessmodel文件
public UserBussinessModel( Context context ) {
this.mContext = context;
}
public UserBussinessModel( Context mContext, IRegisterMVP.Presenter mRegisterPresenter ) {
this.mContext = mContext;
this.mRegisterPresenter = mRegisterPresenter;
}
public UserBussinessModel( Context mContext, LoginMVP.Presenter mLoginPresenter ) {
this.mContext = mContext;
this.mLoginPresenter = mLoginPresenter;
}
@Override
public void validateData( ArrayMap< String, String > userParameters ) {
Call< MainModel< Fortune > > jsonObjectCall = this.mFortuneService.getSpesificFortuneBasedOnUser( userUUID, fortune_id );
jsonObjectCall.enqueue( new Callback< MainModel< Fortune > >() {
@Override
public void onResponse( Call< MainModel< Fortune > > call, Response< MainModel< Fortune > > response ) {
// HOW SHOULD MODEL INVOKE THE PRESENTER METHOD IN ORDER TO ARRANGE VIEW FILES?
}
@Override
public void onFailure( Call< MainModel< Fortune > > call, Throwable t ) {
// HOW SHOULD MODEL INVOKE THE PRESENTER METHOD IN ORDER TO ARRANGE VIEW FILES?
}
} );
}
答案 0 :(得分:1)
如果您有兴趣在Android中实施MVP,请参阅Google Android Architecture Blueprints。
关于你的问题:
因为Model会决定哪个方法应该在演示者中工作,并且根据选择的方法,演示者将调用视图方法。
这不是做MVP的常用方法。在MVP中,模型是被动的,演示者是代理。
(来自MVP Wikipedia page的图表)
根据上图,演示者操纵模型,模型不了解或关心演示者。当模型需要通知演示者状态更改事件时,通过演示者注册来自模型的回调来完成。这在蓝图示例中也很清楚:
curl -v -L http://ansgar-skoda.tumblr.com/post/96703389502
演示者依赖于模型(任务存储库),但任务存储库不知道或不关心谁正在使用它。虽然链接的示例没有显示从模型层传播到演示者的状态更改事件,但是如果存在,则可能通过在演示者层内注册回调来完成。如下所示:
@Inject
TasksPresenter(TasksRepository tasksRepository, TasksContract.View tasksView) {
mTasksRepository = tasksRepository;
mTasksView = tasksView;
}
同样,该示例还显示与您的加载类似,并将其正确放置在演示者中:
mTasksRepository.registerStateChangeEvent(this);
由于private void loadStatistics() {
mStatisticsView.setProgressIndicator(true);
// The network request might be handled in a different thread so make sure Espresso knows
// that the app is busy until the response is handled.
EspressoIdlingResource.increment(); // App is busy until further notice
mTasksRepository.getTasks(new TasksDataSource.LoadTasksCallback() {
//snip
没有采取与视图或演示者相关的任何依赖关系,并且被演示者操纵为患者,因此我们仍然保持关注点分离。