Comment utiliser BehaviorRelay comme alternative à la Variable dans RxSwift?
Comme de RxSwift4, Variable
est déplacé à Deprecated.swift
marquant la possible dévalorisation de Variable
dans l'avenir. Une alternative proposée à Variable
BehaviorRelay
. En postant cette question, comme je n'ai pas pu trouver beaucoup de tutoriel sur le web en utilisant BehaviorRelay
je pose une question aussi fondamentale ici dans SO.
supposons que j'ai un appel webService en cours et que je reçois un morceau de données qui est JSONArray, en analysant un objet JSON un par un, je mets à jour la valeur de ma Variable la propriété
Voici ma déclaration de variable
var myFilter = Variable<[MyFilterModel]>([MyFilterModel(data: "{:}")])
sur l'obtention d'un nouvel élément à chaque fois que je mettrais à jour ma Variable comme
myFilter.value.append(newModel)
comme la Variable était liée à CollectionView, collectionVie mettait à jour son UI immédiatement avec l'objet nouvellement ajouté.
problem with BehaviorRelay
Maintenant ma déclaration ressemble à
var myFilter = BehaviorRelay<[MyFilterModel]>(value: [MyFilterModel(data: "{:}")])
Mais le plus gros problème est myFilter.value
est readOnly. Alors, évidemment
myFilter.value.append(newModel)
n'est pas une solution. J'ai compris que je peux utiliser accept
plutôt.
mais maintenant, quand j'essaie d'analyser chaque élément en réponse et mettre à jour la valeur de myFilter
self?.expertsFilter.accept(newModel)
La déclaration ci-dessus donne une erreur en citant
ne peut pas convertir la valeur de NewModel en type d'argument attendu [NewModel]
Évidemment, il attend un tableau et pas un élément individuel.
palliatif:
Solution 1:
ainsi une solution est d'accumuler toute la réponse dans un tableau temporaire et une fois fait déclencher self?.expertsFilter.accept(temporary_array)
Solution 2:
Si je dois envoyer onNext
événement à l'abonné sur l'analyse de chaque élément, j'ai besoin de copier la valeur de l'auto?.expertsFilter à new Array, ajouter l'élément nouvellement parsé à elle et retourner le nouveau tableau.
Solution 3:
se débarrasser de BehaviorRelay
et utiliser BehaviorSubject
/PublishSubject
les deux premiers semblent déprimants, parce qu'il peut y avoir un besoin de déclencher L'UI sur l'analyse de chaque élément Je ne peux pas attendre jusqu'à ce que la réponse entière est analysée. Il est donc évident que la solution1 n'est pas très utile.
la seconde solution est beaucoup plus horrible car elle crée un nouveau tableau (je sais qu'elle est temporaire et qu'elle sera libérée) à chaque fois pour envoyer onNext événement.
Question:
Parce que BehaviorRelay
est proposé comme alternative à Variable
suis en dilemme, je suis à l'aide de accept
correctement?? Est-il un meilleur moyen de le résoudre?
s'il vous Plaît aider
3 réponses
avez-vous envisagé de créer simplement un nouveau tableau à partir de la valeur existante sur le relais, en ajoutant, puis en appelant accept
?
myFilter.accept(myFilter.value + [newModel])
réponse de Dalton, ici est une extension pratique:
extension BehaviorRelay where Element: RangeReplaceableCollection {
func acceptAppending(_ element: Element.Element) {
accept(value + [element])
}
}
je voudrais faire quelque chose comme ça -
let requests = PublishSubject<Observable<ServerResponse>>.create()
let responses: Observable<ServerResponse> = requests.switchLatest()
let parsed: Observable<[ParsedItem]> = responses
.flatMap { Observable.from().map { parse() }.toArray() }
parsed.bind(to: ui)
// repeated part
let request1: Observable<ServerResponse> = servive.call()
request.onNext(request1)