使用类注入引用Observable

时间:2018-06-07 16:55:31

标签: swift mvvm reactive-programming rx-swift

请考虑以下结构:

class UpModel {
    var isThisRealLife: Variable<Bool>

    required init(model: UpperModel) {
        isThisRealLife = Variable(upperModel.isThisRealLife) //true
        testFlagChange()
    }

    private func testFlagChange() {
        DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
            self.isThisRealLife = false
        }
    }
}

此模型由UpperViewModel实例化,通过注入它自己的UpperModel实例,如下所示:

class UpperViewModel {
    init() {
        let upperModel = UpperModel()

        let upModel = UpModel(model: upperModel)
        let upViewModel = UpViewModel(model: upModel)
    }
}

现在我有UpViewModel课程:

class UpViewModel {
    let bag = DisposeBag()

    init(model: UpModel) {
        let upModelVariable = Variable(model)
        let lowViewModel = LowViewModel<LowModel>(model: upModelVariable)

        upModelVariable.asObservable().flatMap({ $0.isThisRealLife.asObservable() }).subscribe(onNext: { value in
            print("changed to \(value) -- at UpVM") //1
        }).disposed(by: bag)
    }
}

1:在3秒后对标志更改做出正确反应。

好的,到目前为止,非常好。 但现在我想继续发送此UpClass引用,以便其他类可以对isThisRealLife属性的更改做出反应。

这是我的LowViewModel,他收到UpModel参考:

class LowViewModel<Model: LowModel> {
    let bag = DisposeBag()
    let lowModel: LowModel

    required init(model: Variable<UpModel>) {
        lowModel = Model(model: model.value) 

        model.asObservable().flatMap({ $0.isThisRealLife.asObservable() }).subscribe(onNext: { value in
            print("changed to \(value) -- at LowVM") //2
        }).disposed(by: bag)
    }
}

2:这不会对标志更改做出反应。

这是LowModel,但我还没有使用它,因为我似乎在上一步失去了对isThisRealLife属性的引用:

class LowModel {
    var isThisRealLife: Observable<Bool>

    required init(model: UpModel) {
        isThisRealLife = model.isThisRealLife.asObservable
    }
}

备注

  • 我了解Variable已被弃用,我会尽快重构BehaviorRelay
  • 我试图尽量减少示例以说明问题,但当然问题可能在更大的范围内 - 在这种情况下,我很乐意根据需要提供更多信息。
  • 有许多协议可以使事物变得通用和可重用,所以我删除了所有这些协议以尝试关注(至少我认为是)这个问题。 GUI现在也不重要,只是业务逻辑。

如果有人感兴趣,可以使用更长的语境:

我和我的团队正在为我们的项目开发一个新的架构。 由于我们的设计相当一致,我们正在验证使用&#34; components&#34;这一概念,这是一组可在整个应用程序中重复使用的View,ViewModel和Model。

主要思想是每个屏幕都是一组带有ViewController,ViewModel和Model的MVVM,它们实现了&#34;组件&#34;如所须。我们正在实施Reactive以允许某些组件在&#34; parent&#34; /&#34; upper&#34;模型。

我已经在RxSwift工作了近一年了,但我工作的项目相当简单,用法很重复,所以我对这个问题的了解变得很窄(这是我的错误,ofc )。

感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

我认为你对传递值或引用init感到困惑。

我不确定这个设计的目标是什么......我无法理解,但我想你的问题是......

在#1中你创建了新的局部变量
let upModelVariable =变量(模型)

<#>在2#中你注册了一个func参数作为observable,但是它因init返回而死亡,因为它是通过值传递的(尝试inout)

这就是为什么#1有效,#2没有。

尝试使用inout传递这样的引用[看看它是否按你的意愿工作]

    init(model: UpModel) {
            var upModelVariable = Variable(model)
            let _ = LowViewModel<LowModel>(model: &upModelVariable)

            upModelVariable.asObservable().flatMap({ $0.isThisRealLife.asObservable() }).subscribe(onNext: { value in
                print("changed to \(value) -- at UpVM") //1
            }).disposed(by: bag)
        } 
class LowViewModel<Model: LowModel> {
    let bag = DisposeBag()
    let lowModel: LowModel
    required init( model: inout Variable<UpModel>) {
        lowModel = Model(model: model.value)

        model.asObservable().flatMap({ $0.isThisRealLife.asObservable() }).subscribe(onNext: { value in
            print("changed to \(value) -- at LowVM") //2
        }).disposed(by: bag)
    }
}