3 votes

Observation d'une variable @Published à partir d'un autre objet

J'essaie de faire en sorte qu'un objet écoute les modifications de la propriété d'un autre objet. Je l'ai fait fonctionner comme indiqué ci-dessous, mais je préférerais que l'objet observateur ne sache rien du modèle, seulement de la propriété.

class Model : ObservableObject{
    @Published var items: [Int] = []
}

class ObjectUsingItems{
    var itemObserver: AnyCancellable?
    var items: [Int] = []

    func observeItems(model: Model){
        itemObserver = model.$items
            .sink{ newItems in
                self.items = newItems
                print("New Items")
        }
    }
}

Pour le moment, je commence à observer le model.items comme suit - ce qui fonctionne :

let model = Model()
let itemUser = ObjectUsingItems()

itemUser.observeItems(model: model)
model.items.append(1) // itemUser sees changes

Malheureusement, je n'arrive pas à trouver ce qui doit être le paramètre de la méthode observeItems pour qu'elle fonctionne sans rien savoir du modèle - comme ceci :

class ObjectUsingItems{
    var itemObserver: AnyCancellable?
    var items: [Int] = []

    func observeItems(propertyToObserve: WhatGoesHere?){
        itemObserver = propertyToObserve
            .sink{ newItems in
                // etc.
        }
    }
}

Et ensuite l'appeler comme ça :

itemUser.observeItems(XXX: model.$items)

Quelqu'un peut-il m'expliquer ce que je dois faire ? Merci !

2voto

New Dev Points 32306

Vous pouvez simplement accepter un éditeur comme paramètre, si vous ne vous souciez pas de l'origine de la valeur.

Dans votre cas très spécifique, ça pourrait l'être :

func observeItems(propertyToObserve: Published<[Int]>.Publisher) {
   itemObserver = propertyToObserve
                     .sink { self.items = $0 }
}

Mais cela pourrait être trop restrictif - pourquoi seulement cet éditeur spécifique ? En principe, vous ne devriez pas vous soucier de l'éditeur - tout ce qui vous importe est la valeur de sortie et le type d'erreur. Vous pouvez le rendre générique pour n'importe quel éditeur, tant que son Output est [Int] et l'échec est Never (comme celle de l @Published un) :

func observeItems<P: Publisher>(propertyToObserve: P) 
   where P.Output == [Int], P.Failure == Never {

   itemObserver = propertyToObserve
                     .sink { self.items = $0 }
} 

L'utilisation serait quelque chose comme ceci :

let model = Model()
let itemUser = ObjectUsingItems()

itemUser.observeItems(propertyToObserve: model.$items)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X