1

Alors, je viens de commencer à expérimenter avec LiveData - Je suis occupé avec un nouveau projet, où je me sers ViewModel ainsi que LiveData - avec quelques-uns des RESTFul services que j'utilise Pour récupérer des données, ils ne prennent aucun paramètre et retournent des données.Apporter des changements à LiveData au travail « redo » dans ViewModel

Une configuration typique du paradigme MVVM avec LiveData ressemble beaucoup à ceci:

public class MyActivity extends AppCompatActivity { 
    public void onCreate(Bundle savedInstanceState) { 
     MyViewModel model = ViewModelProviders.of(this).get(MyViewModel.class); 
     model.getUsers().observe(this, users -> { 
      // update UI 
     }); 
    } 
} 

Maintenant, lorsque nous quittons cette activité, et aller à une nouvelle activité, en utilisant une intention ou d'autres moyens, et non en appuyant sur le bouton de retour (donc, finalize n'est pas appelé) - et puis revenir à MyActivity - nous bien sûr ne récupérons pas le users à nouveau, car nous devrions toujours avoir ces données. Cependant, que se passe-t-il si nous voulions les récupérer à nouveau?

La seule façon de le faire correctement, de ce que je l'ai regardé, semble appeler « AssignerValeur » sur le getUsers()LiveData objet

Quelque chose comme ceci:

public class MyActivity extends AppCompatActivity { 
    public void onResume() { 
    viewModel.setActive(true); 
    } 
} 

Et le ViewModel regarderait comme ceci:

private final MutableLiveData<Boolean> activeLiveData = new MutableLiveData<>(); 

ViewModel(ViewModelRepo repo){ 
     this.repo = repo; 

     results = Transformations.switchMap(activeLiveData, active ->{ 
     if(active){ 
      return repo.getUsers(); 
     }else { 
      return AbsentLiveData.create(); //"Null live data" 
     } 
     }); 
    } 

    LiveData<Users>> getUsers() { 
    return results; 
    } 

//This could be called "update" with no params 
    void setActive(boolean active) { 
    activeLiveData.setValue(active); 
    } 

La seule raison pour laquelle j'ai décidé de le faire est que Google ne veut pas que nous fassions cela :

class MyViewModel extends ViewModel { 
    private final PostalCodeRepository repository; 
    public MyViewModel(PostalCodeRepository repository) { 
     this.repository = repository; 
    } 

    private LiveData<String> getPostalCode(String address) { 
     // DON'T DO THIS 
     return repository.getPostCode(address); 
    } 
} 

Pour cette raison:

Si cela est la mise en œuvre, l'interface utilisateur aurait besoin d'annuler l'enregistrement de la LiveData précédente et se réinscrire à la nouvelle instance à chaque fois qu'ils appellent GetPostalCode (). De plus, si l'interface utilisateur est recréée, elle déclenche un autre appel à repository.getPostCode() au lieu d'utiliser le résultat de l'appel précédent .

Y at-il une meilleure façon d'obtenir le ViewModel à « refaire » son appel repo.getUsers()? Peut-être que je pourrais juste faire une méthode qui dit "Update()" au lieu de "active" mais quand même - faire la même chose différemment.

Répondre

1

Eh bien, ici vous faites la récupération dans le créateur du ViewModel, qui verrouille les choses en place. Habituellement, ils conseillent d'aller chercher les données dans le getter, si les données ne sont pas déjà là.

donc une bonne option serait d'utiliser le modèle régulier d'abord:

private MutableLiveData<Users> users = null; 

ViewModel(ViewModelRepo repo){ 
     this.repo = repo; 
    } 

    LiveData<Users> getUsers() { 
    if (users = null) { 
     fetchUsers(); 
    } 
    return users; 
    } 

    public void fetchUsers() { 
    users.postValue(repo.getUsers()); 
    } 

Et puis de votre activité/Fragment, chaque fois que vous vous sentez nécessaire pour « rafraîchir les utilisateurs », vous voulez simplement appeler viewModel.fetchUsers();