简体   繁体   English

使用RxSwift和RxCocoa绑定模型并更新单元格

[英]Bind model and update cell with RxSwift and RxCocoa

I have a product$ which is Variable<[Product]>([]) and have a tableview with custom cell which has textfield. 我有一个product $,它是Variable <[Product]>([[)),并且有一个带有自定义单元格且具有文本字段的表格视图。 What I want is to update the cell when model change and when text of textfield change I want to update my model. 我想要的是在模型更改时和文本字段文本更改时更新单元格,我想更新模型。 Here what I did. 这是我做的。

products$.asObservable()
        .bind(to: self.tableViewCal.rx.items(cellIdentifier: "edittingCell")){ (row, product: Product, cell: CaloriesEdittingCell) in
            cell.lblContentName.text = self.products$.value[row].name ?? ""
            cell.textValue.text = "\(self.products$.value[row].price ?? 0)"
            cell.textValue.rx.text
                .map({ value -> Float in
                    return (value! as NSString).floatValue
                })
                .subscribe({value in
                    self.products$.value[row].price = value.element
                    print(product)
                }).disposed(by: self.bag)
        }.disposed(by: bag)

Obviously, It will stuck in loop. 显然,它将陷入循环。 So What I did is I created a another tempProduct$ with same datatype and assign the values of product$ to tempProduct$. 所以我要做的是创建另一个具有相同数据类型的tempProduct $并将product $的值分配给tempProduct $。 Here is the code 这是代码

tempProduct$.value = products$.value
tempProduct$.asObservable()
        .bind(to: self.tableViewCal.rx.items(cellIdentifier: "edittingCell")){ (row, product: Product, cell: CaloriesEdittingCell) in
            cell.lblContentName.text = self.products$.value[row].name ?? ""
            cell.textValue.text = "\(self.products$.value[row].price ?? 0)"
            cell.textValue.rx.text
                .map({ value -> Float in
                    return (value! as NSString).floatValue
                })
                .subscribe({value in
                    self.products$.value[row].price = value.element
                    print(product)
                }).disposed(by: self.bag)
        }.disposed(by: bag)

It works but If there is better solution then please let me know. 它可以工作,但是如果有更好的解决方案,请告诉我。 Thanks in advance. 提前致谢。

A better architectural choice for that sort of things is to adhere to unidirectional data flow principle. 对于这类事情,更好的体系结构选择是遵守单向数据流原理。 See https://redux.js.org/docs/basics/DataFlow.html for general intro. 有关一般介绍,请参见https://redux.js.org/docs/basics/DataFlow.html A possible implementation with RaspSwift would be like - 使用RaspSwift的可能实现将是-

struct MyState: RaspState {
    var price: Float = 0.0

    mutating func apply(event: RaspEvent) {
        switch event {
        case let priceEvent as PriceEvent:
            self.price = priceEvent.price
        default:
        break
        }
    }
}

struct PriceEvent: RaspEvent {
    let price: Float
}

let myAggregator = RaspAggregator<MyState>(initial: MyState())

let priceSelector = RaspSelector<MyState, Float> { state -> Float in
    let value: Float = state.price
    return value
}

let price = myAggregator.select(selector: priceSelector)

price.bind(to: self.tableViewCal.rx.items(cellIdentifier: "edittingCell")){ (row, product: Product, cell: CaloriesEdittingCell) in
            cell.lblContentName.text = self.products$.value[row].name ?? ""
            cell.textValue.text = "\(self.products$.value[row].price ?? 0)"
            cell.textValue.rx.text
                .map({ value -> Float in
                    return (value! as NSString).floatValue
                })
                .subscribe({value in
                    myAggregator.manual(PriceEvent(price: value) as RaspEvent)
                    print(product)
                }).disposed(by: self.bag)
        }.disposed(by: bag)

Obviously, you can store a lot of other stuff in state object too, besides price. 显然,除了价格之外,您还可以在状态对象中存储许多其他内容。

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM