尝试创建具有两个相关表一对一的会议室数据库。通过外键进行连接,但是我发现用实时数据获取数据很困难,我不知道这种获取数据是否正确。
class GraphFragment : Fragment() {
private lateinit var graphVM: GraphVM
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.fragment_graph, container, false)
graphVM = ViewModelProviders.of(this).get(GraphVM::class.java)
graphVM.graphFiles.observe(this, Observer<List<GraphEntity>> {
it?.let {
graphVM.getDataFiles( it.map { it.fileID })
}
})
graphVM.dataFiles.observe(this, Observer<List<FileEntity>> {
it?.let {
// work with FileEntity
}
})
}
Viewmodel
class GraphVM(application: Application) : AndroidViewModel(application) {
private var graphFilesRepository: GraphRepository = GraphRepository(application)
private var fileRepository: FileRepository = FileRepository(application)
var graphFiles: LiveData<List<GraphEntity>> = MutableLiveData()
private set
var dataFiles: LiveData<List<FileEntity>> = MutableLiveData()
private set
init {
// this work
graphFiles = graphFilesRepository.getAllFiles()
}
fun getDataFiles(listOfFileIDs: List<Long?>) {
// this not
dataFiles = fileRepository.getFilesDataByID(listOfFileIDs)
}
}
FileRepository
class FileRepository(application: Application) {
private var fileDao: FileDao
init {
val database: FileDatabase = FileDatabase.getInstance(application)!!
fileDao = database.fileDao()
}
/..
../
fun getFilesDataByID(listOfFileIDs: List<Long?>): LiveData<List<FileEntity>> {
return fileDao.queryFilesEntityByID(listOfFileIDs)
}
}
道
@Dao
interface FileDao {
/..
../
@Query("SELECT * FROM file_data WHERE id IN (:listOfFileIDs)")
fun queryFilesEntityByID(listOfFileIDs : List<Long?>): LiveData<List<FileEntity>>
}
因此,当我在init中分配任务时,实时数据会正确触发,但是当我尝试执行以下操作时:
graphVM.getDataFiles( it.map { it.fileID })
Livedata 是分配的,但不触发。我知道它分配正确,因为当我删除文件时,会从FileRepository更改值,实时数据接收onChange和观察者。我想知道有什么方法可以解决此问题,因此我可以在分配任务时使用livedata从会议室数据库接收值。
@PS发现了问题。当我尝试在Observer {...}中获取DataFiles时,它不起作用,但是当我从onCreateView {...}中调用函数时,它起作用了。 有解决办法吗?
答案 0 :(得分:0)
这里的主要问题是您需要观察并更新LiveData
的一个实例,但是对getDataFiles()
的调用会覆盖dataFiles
字段。
首选解决方案是向客户端提供请求LiveData
,并在客户端观察更新:
class GraphVM(application: Application) : AndroidViewModel(application) {
//...
fun getDataFiles(listOfFileIDs: List<Long?>): LiveData<List<FileEntity>> {
return fileRepository.getFilesDataByID(listOfFileIDs)
}
}
如果此方法不合适,则可以使用MediatorLiveData
切换数据源:
class GraphVM(application: Application) : AndroidViewModel(application) {
private var fileRepository: FileRepository = FileRepository(application)
private val dataFiles = MediatorLiveData<List<FileEntity>>()
private var request: LiveData<List<FileEntity>>? = null
// expose dataFiles as LiveData
fun getDataFiles(): LiveData<List<FileEntity>> = dataFiles
@MainThread
fun getDataFiles(listOfFileIDs: List<Long?>) {
// create new request to repository
val newRequest = fileRepository.getFilesDataByID(listOfFileIDs)
val observer = Observer<List<FileEntity>> { list ->
// remove previous subscription
request?.run { dataFiles.removeSource(this) }
// setup fresh data
dataFiles.value = list
// remember last request
request = newRequest
}
// register new observable data source (LiveData)
dataFiles.addSource(newRequest, observer)
}
}