简体   繁体   English

如何实现与INotifyPropertyChanged等效的RxJava来生成Observable数据模型?

[英]How can I implement the RxJava equivalent of INotifyPropertyChanged to make an Observable data model?

I'm new to Java and new to Rx. 我是Java的新手,也是Rx的新手。 I'm in at the deep end. 我处于深渊。 I'm at very early stages of writing an android app that will use an MVC (Model-View-Controller) pattern and I'm experimenting with various ways of doing that, in particular RxJava. 我正处于编写将使用MVC(模型 - 视图 - 控制器)模式的Android应用程序的早期阶段,我正在尝试各种方法,特别是RxJava。 My idea is to make my Model an Observable and my View the Observer . 我的想法是让我的模型Observable和我查看Observer The model (or a wrapper class) would then emit a new copy of the model each time its data changes. 然后,模型(或包装类)每次数据更改时都会发出模型的新副本。 In .net I'd be thinking about using INotifyPropertyChanged . 在.net中我会考虑使用INotifyPropertyChanged

I think I need to implement a custom Observable - but how? 我想我需要实现一个自定义Observable - 但是如何? There's plenty of documentation about how to convert collections into observables, but this doesn't fit my use-case as I don't have a collection - just a single item, the data model. 有很多关于如何将集合转换为observable的文档,但这不适合我的用例,因为我没有集合 - 只有一个项目,即数据模型。 Is there a way to do this? 有没有办法做到这一点? Remember I'm developing for Android so I can't use lambdas or anything fancy like that. 记住我正在为Android开发,所以我不能使用lambdas或类似的任何东西。

[Update] Thanks to André Staltz's answer, I think I am off the starting blocks. [更新]感谢AndréStaltz的回答,我认为我不在起跑线上了。 I came up with this class: 我想出了这堂课:

import rx.Observable;
import rx.subjects.BehaviorSubject;

public class ObservableModel<TModel>
    {
    private TModel                  modelData;
    private BehaviorSubject<TModel> modelStream;
    private boolean disposed = false;

    public ObservableModel(TModel modelData)
        {
        this.modelData = modelData;
        modelStream = BehaviorSubject.create(modelData);
        }

    public TModel getModelData()
        {
        if (disposed)
            {
            throw new UnsupportedOperationException("The object has been disposed");
            }
        return modelData;
        }

    public void setModelData(TModel modelData)
        {
        if (disposed)
            {
            throw new UnsupportedOperationException("The object has been disposed");
            }
        this.modelData = modelData;
        modelStream.onNext(this.modelData);
        }

    public Observable<TModel> getObservable()
        {
        return modelStream;
        }

    public void close()
        {
        modelStream.onCompleted();
        modelStream = null;
        modelData = null;
        disposed = true;
        }
    }

You don't need to implement a custom Observable, because Observables are generic and are meant to be used by just specifying which type the Observable is of. 您不需要实现自定义Observable,因为Observables是通用的,并且只需指定Observable所属的类型即可使用。

If you look at your model objects changing over time, you really have a collection of model objects over time: [modelObject1, modelObject2, modelObject3, ...] 如果你看一下随着时间的推移而变化的模型对象,你真的会随着时间的推移拥有一组模型对象:[modelObject1,modelObject2,modelObject3,...]

One simple way of implementing this is to have a static Observable of type FooBarModel, that is, Observable<FooBarModel> : 实现此目的的一种简单方法是使用类型为FooBarModel的静态Observable,即Observable<FooBarModel>

public class FooBarModel {

    public static BehaviorSubject<FooBarModel> fooBarStream;

    // ...

    private int fooBarMember1;
    private int fooBarMember2;
}

Instead of Observable<FooBarModel> , we used a Subject (choose either PublishSubject or BehaviorSubject, as you wish), which is akin to an Event bus. 而不是Observable<FooBarModel> ,我们使用了Subject(根据需要选择PublishSubject或BehaviorSubject),它类似于Event总线。 Everytime you change fooBarMember1 or fooBarMember2 in FooBarModel, you emit the instance of FooBarModel by calling fooBarStream.onNext(this) , and every subscriber of FooBarModel.fooBarStream will see the new instance of FooBarModel. 每次在FooBarModel中更改fooBarMember1或fooBarMember2时,都会通过调用fooBarStream.onNext(this)来发出fooBarStream.onNext(this)的实例,并且FooBarModel.fooBarStream的每个订阅者FooBarModel.fooBarStream将看到FooBarModel.fooBarStream的新实例。

However, this is really just one flavour of solution, and there are many other ways of doing this. 然而,这实际上只是一种解决方案,还有很多其他方法可以做到这一点。 If your FooBarModel depends on updates from some other entity "Baz", then it might make more sense to replace the BehaviorSubject with Observable , and instead of directly feeding in new instances, you just create the Observable by using some transformation/combination functions (such as map(), flatMap(), delay(), filter(), etc) on the Observables of "Baz". 如果你的FooBarModel依赖于来自其他实体“Baz”的更新,那么将BehaviorSubject替换为Observable可能更有意义,而不是直接输入新实例,只需使用一些转换/组合函数创建Observable(如作为“Baz”的Observables上的map(),flatMap(),delay(),filter()等)。


One good RxJava MVC architecture is to have all three Model, View, and Controller be Observables which are circularly dependent to each other. 一个好的RxJava MVC架构是让所有三个Model,View和Controller都是Observables,它们彼此循环相关。

The View observes updates from the Model's Observable, and exports public Observables for click events, keyboard events, inputs, etc. View观察Model的Observable的更新,并导出公共Observables的click事件,键盘事件,输入等。

The Controller observes the View's user input Observables, and processes those inputs to export them as Observables of "processed user input", in a format suitable for the Model. Controller观察View的用户输入Observables,并处理这些输入,以适合Model的格式将它们导出为“已处理用户输入”的Observable。 For instance, if the View has an Observable of search field textual content, then the Controller respectively exports an Observable of lowercase search field textual content. 例如,如果View具有Observable of search字段文本内容,则Controller分别导出Observable of lowercase搜索字段文本内容。 Another example: the Controller interprets click events from the View as database requests. 另一个示例:Controller将View中的单击事件解释为数据库请求。

The Model observes "processed user input" from the Controller, and exports Observables of application data. 模型从Controller观察“已处理的用户输入”,并导出应用程序数据的Observable。

In such scenario you wouldn't necessarily need Subjects. 在这种情况下,您不一定需要主题。 The benefit of this approach is pure separation of concerns: no entity updates any other entity imperatively . 这种方法的好处是纯粹的关注点分离:任何实体都不会强制更新任何其他实体。 All the Controller logic is entirely specified only in Controller, no where else. 所有Controller逻辑完全仅在Controller中指定,而不是在其他地方指定。 And also you have a clean picture of inputs and outputs. 此外,您还可以清楚地了解输入和输出。 Entities observe other entities and export some of their data as Observables. 实体观察其他实体并将其一些数据导出为Observable。 There is no call "controller.updateThisAndThat()" in the View. 视图中没有调用“controller.updateThisAndThat()”。

But for starters, use Subjects since they are easy to reason about, with regard to updating the observers. 但对于初学者来说,在更新观察者方面,使用主题因为它们易于推理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我如何在 Observable RxJava 中测试参数 - How I can test arguments in Observable RxJava RxJava:如何使一次获取和重用可观察到? - RxJava: How do I make a fetch-once-and-reuse Observable? RxJava。 如何让 Observable 计时器在后台运行? - RxJava. How do I make the Observable timer run in the background? RxJava:如何重置长时间运行的热可观察链? - RxJava: How can I reset a long running hot observable chain? 我怎样才能停止观察一个 observable 而不在 RxJava2 中处理它? - How can I stop observing an observable without disposing it in RxJava2? 如何返回一个RxJava Observable,保证不会抛出OnErrorNotImplementedException? - How can I return an RxJava Observable which is guaranteed not to throw OnErrorNotImplementedException? 在 RxJava 2 中,如何使一个 Observable 发出另一个 Observable 发出的组合项? - How to Make an Observable that Emits Combined Items Emitted by Another Observable in RxJava 2? RXjava 为对象更新实现一个可观察的对象 - RXjava implement an observable for an object update 在返回订阅服务器之前,如何拦截可观察对象并在RxJava中修改它? - How can I intercept an observable object and modify it in RxJava before returning to Subscriber? 等效于RxJava的RxJS.pausable(Observable) - equivalent of RxJS.pausable(Observable) for RxJava
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM