是否可以在没有工厂的情况下在公共方法中将id参数传递给AndroidViewModel?

是否可以在没有工厂的情况下在公共方法中将id参数传递给AndroidViewModel?,android,android-architecture-components,Android,Android Architecture Components,我在看Android架构组件示例中的BasicSample应用程序。在ProductViewModel.java文件中,一些注释如下: 不是 在这种情况下实际上是必要的,因为产品ID可以在公共方法中传递 根据我对评论的理解,我想知道是否有可能在不使用工厂的情况下将productId传递给ProductViewModel,以及如何做到这一点 我已经实现了转换,我知道我可以使用switchMap传递productId。但是我正在寻找一种用单个id初始化模型的方法 public class Produ

我在看Android架构组件示例中的BasicSample应用程序。在ProductViewModel.java文件中,一些注释如下:

不是 在这种情况下实际上是必要的,因为产品ID可以在公共方法中传递

根据我对评论的理解,我想知道是否有可能在不使用工厂的情况下将productId传递给ProductViewModel,以及如何做到这一点

我已经实现了转换,我知道我可以使用switchMap传递productId。但是我正在寻找一种用单个id初始化模型的方法

public class ProductViewModel extends AndroidViewModel {

    private final LiveData<ProductEntity> mObservableProduct;

    public ObservableField<ProductEntity> product = new ObservableField<>();

    private final int mProductId;

    private final LiveData<List<CommentEntity>> mObservableComments;

    public ProductViewModel(@NonNull Application application, DataRepository repository,
            final int productId) {
        super(application);
        mProductId = productId;

        mObservableComments = repository.loadComments(mProductId);
        mObservableProduct = repository.loadProduct(mProductId);
    }
公共类ProductViewModel扩展了AndroidViewModel{
私有最终LiveData mObservableProduct;
公共ObservableField product=新ObservableField();
私有最终int-mProductId;
私有最终LiveData mObservableComments;
public ProductViewModel(@NonNull应用程序、数据存储库、,
最终int产品ID){
超级(应用);
MPProductId=productId;
mObservableComments=repository.loadComments(MPProductId);
mObservableProduct=repository.loadProduct(mProductId);
}

/**
*创建者用于将产品ID注入ViewModel
*
*此创建者将展示如何将依赖项注入ViewModels。它不是
*在这种情况下实际上是必要的,因为产品ID可以在公共方法中传递。
*/
公共静态类工厂扩展了ViewModelProvider.NewInstanceFactory{
@非空
私有最终应用程序映射应用程序;
私有最终int-mProductId;
私有最终数据存储库;
公共工厂(@NonNull应用程序,int-productId){
应用=应用;
MPProductId=productId;
mRepository=((basicap)应用程序).getRepository();
}
@凌驾
公共T创建(类modelClass){
//未检查
返回(T)新产品视图模型(MapApplication、mRepository、MPProductId);
}
}
}

产品ID从哪里来

  • 如果它是从存储库(数据库或web服务)加载的,我想您不必在ViewModel上公开它

  • 如果它是一个“动态”值,存储在SharedReferences中或从视图设置,则可以按如下方式公开设置器


关于样本,当评论说:

可以在公共方法中传递产品ID

这是指您可以创建公共setter方法的事实

由于
productId
用于从数据库获取LiveData,因此您应该使用
switchMap
,如您所述。这是因为
switchMap
允许您查找和更新
LiveData
所指向的内容,而无需重新设置观察者。如果您没有使用
开关映射
,则需要告诉您的活动观察新查找的
LiveData
,并可能停止观察旧的
LiveData
对象

还有一个注意事项-工厂在这里也很有用,因为您正在通过构造函数传入或注入
DataRepository
依赖项。这是将存储库放入类中的更好方法,因为在测试时很容易模拟存储库

考虑到这一点,如果您希望在工厂中执行此操作,那么您的代码可能如下所示:

public class ProductViewModel extends AndroidViewModel {

    private final LiveData<ProductEntity> mProduct;
    private final LiveData<List<CommentEntity>> mComments;
    private final MutableLiveData<Integer> mProductId = new MutableLiveData<>();


    public ProductViewModel(@NonNull Application application) {
        super(application);

        // Have some way to get your repository, this is not great for testing...
        Repository repository = ((BasicApp) application).getRepository();

            mProduct = Transformations.switchMap(mProductId, id -> {
            return repository.loadProduct(id);
        }

            mComments = Transformations.switchMap(mComments, id -> {
            return repository.loadComments(id);
        }
    }

    public void setProductId(int productId) {
       mProductId.setValue(productId); // This will trigger both of those switchMap statements
    }

}
公共类ProductViewModel扩展了AndroidViewModel{
私有最终LiveData MPProduct;
私有最终LiveData mComments;
private final MutableLiveData MPProductId=新的MutableLiveData();
public ProductViewModel(@NonNull应用程序){
超级(应用);
//有一些方法来获取您的存储库,这对于测试来说不是很好。。。
Repository Repository=((BASICAP)应用程序).getRepository();
MPProduct=Transformations.switchMap(MPProductID,id->{
返回repository.loadProduct(id);
}
mComments=Transformations.switchMap(mComments,id->{
返回repository.loadComments(id);
}
}
public void setProductId(int productId){
setValue(productId);//这将触发这两个switchMap语句
}
}

以防有人混淆。它应该是
mComments=Transformations.switchMap(MPProductId,…
 public void setProductId(int productId) {
       if(mProductId == -1) { // or check mObservableComments 
              mProductId = productId;
              mObservableComments = repository.loadComments(mProductId);
              mObservableProduct = repository.loadProduct(mProductId);
       }
}
public class ProductViewModel extends AndroidViewModel {

    private final LiveData<ProductEntity> mProduct;
    private final LiveData<List<CommentEntity>> mComments;
    private final MutableLiveData<Integer> mProductId = new MutableLiveData<>();


    public ProductViewModel(@NonNull Application application) {
        super(application);

        // Have some way to get your repository, this is not great for testing...
        Repository repository = ((BasicApp) application).getRepository();

            mProduct = Transformations.switchMap(mProductId, id -> {
            return repository.loadProduct(id);
        }

            mComments = Transformations.switchMap(mComments, id -> {
            return repository.loadComments(id);
        }
    }

    public void setProductId(int productId) {
       mProductId.setValue(productId); // This will trigger both of those switchMap statements
    }

}