首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Mosby MVI:不一致的意图绑定行为

Mosby MVI:不一致的意图绑定行为
EN

Stack Overflow用户
提问于 2017-02-20 13:31:03
回答 2查看 626关注 0票数 3

我正在使用新的莫斯比MVI库作为一个新的演示应用程序。当在演示程序中定义意图时,当视图被附加时触发/发出意图时,它是不一致的。

例如:让我们在活动中定义非常简单的意图

代码语言:javascript
复制
public Observable<Boolean> intentLoadData(){
  return Observable.just(true);
}

推荐人将意图绑定如下:

代码语言:javascript
复制
@Override
protected void bindIntents() {
  Observable<MailListViewState> loadData = intent(ExampleViewContract::intentLoadData).flatMap(interactor::loadData)
            .observeOn(AndroidSchedulers.mainThread());
  subscribeViewState(loadData, ExampleViewContract::render);
}

这个意图很好。当导航到不同的活动(详细信息视图)并返回导航时,bindIntents()被称为意图被重新创建。intentLoadData()不发出新项,MviBasePresenter将使用内部BehaviorSubject提供以前的ViewState。

我的问题是:当我稍微调整意图(用于重新加载数据)时,。当视图重新附加时,该意图开始发出一个项。

因此,让我们改变意图,以便:

代码语言:javascript
复制
private PublishSubject<Boolean> mReloadDataSubject = PublishSubject.create();

private void reloadData(){
  mReloadDataSubject.onNext(true);
}

public Observable<Boolean> intentLoadData(){
  return mReloadDataSubject.startWith(true);
}

当导航到一个新的活动并返回时,否。当重新附加视图时,意图将发出一个新项。在我的例子中,这会导致一个新的APU调用到后端来重新加载数据,而不是重用最后一个ViewState。即使从未调用reloadData(),也会发生这种情况。

这种行为感觉非常不一致。当在重新附加视图期间触发意图时,我如何感觉更受控制?

更新:对于我来说,更有趣的是,如何避免在重新附加时自动发出意图,而不完成可观察到的操作。随着PublishSubject的引入,即使只是旋转,活动也会重新加载整个数据。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-02-22 09:53:06

为了回答我自己的问题并总结意见,这是我的解决方案:

首先,我们必须了解Mosby3 MVI是如何还原视图的,例如:旋转之后,来回导航到不同的视图。Mosby3保留演示者的实例。创建视图的新实例时,演示程序将被还原并附加到视图中。onStart()的新视图,演示者将更新意图。因此,新视图创建了新的意图,演示者将使用PublishSubject订阅它们。

如果前面的视图的意图发出了onComplete(),那么PublishSubject也完成了,流也关闭了。绑定到此意图的( intent )逻辑将被取消订阅。因此,这种意图不能再由视图触发。

在原始问题的例子中。Observable.just(true)关闭流。即使视图及其意图被重新创建(旋转后),也不会发出新项。相反,mReloadDataSubject.startWith(true)不发出onComplete(),流是t closed. When the presenter resubscribes to that intent (after rotation), the intent emits thestartsWith(真)`。在本例中,这将导致每次旋转时数据的完全重新加载。

为了触发条件重新加载的意图,RxNavi可能非常有用。

代码语言:javascript
复制
public Observable<Boolean> intentReloadData() {
     //check if the data needs a reload in onResume()
     return RxNavi.observe(this, Event.RESUME)
                  .filter(ignored -> mNeedsReload == true)
                  .map(ignored -> true);
}
票数 2
EN

Stack Overflow用户

发布于 2017-02-20 14:32:49

Mosby MVI尊重反应性流合同。看看intentLoadData()

代码语言:javascript
复制
public Observable<Boolean> intentLoadData(){
  return Observable.just(true);
}

Observable.just(true)不仅调用onNext(true),而且还调用onCompleted()。一旦完成了一个反应流,就不能通过该流发出任何进一步的项。在onComplete()之后,可观测到的流将永久关闭。

在这种情况下,使用PublishSubject是完全可以的,但是为了更好的可读性,我建议不要使用startWith(),而是这样做:

代码语言:javascript
复制
public class MyActivity extends MviActivity<MyView, MailListViewState> {
  private PublishSubject<Boolean> mReloadDataSubject = PublishSubject.create();

  public void onResume(){
    super.onResume();
   // Triggers on screen orientation changes and
   // when navigating back to this screen from back stack
    mReloadDataSubject.onNext(true);
  }

  public Observable<Boolean> intentLoadData(){
    return mReloadDataSubject;
  }

}

顺便说一句。您还可以使用像Trello的纳维这样的库,它为生命周期事件提供了可观察的流,但请记住,如果活动被破坏(即在屏幕方向更改期间),Navi会发出一个onCompleted()事件,因此您最终会遇到相同的情况:如果您想在以后再次触发意图,则必须确保不调用onCompleted()

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42345895

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档