使用架构组件等待未决实时数据的最佳方法

Best approach to waiting on pending live data using architecture components

我正在开发一个通过 apollo-android.

从 graphql 服务器获取数据的应用程序

我在我的 aws rds 数据库上进行了一次提取。我在我的 CalendarFragment.

onCreate() 处执行此提取操作

事情是,在 onViewCreated(),我想将我的文本视图设置为获取的字段之一,名字和姓氏。因此,我 运行 我的 getBarberFullName 方法 returns mBarberFullNameString 值。我正在尝试遵循 UI 控制器显示,而视图模型处理所有逻辑方法。 getBarberFullName 驻留在我的 ViewModel 中。

    public String getBarberFullName() {
        if (appointmentsAreNull()) return mBarberFullName.getValue();
        AppointmentModel am = mMasterAppointments.getValue().get(0);
        String fullName = am.bFirstName;
        fullName = fullName.concat(" " + am.bLastName);
        // Get the logged in barber's full name and set it as mBarberFullName.
        mBarberFullName.setValue(fullName);
        return mBarberFullName.getValue();
    }

其中 mMasterAppointmentsMutableLiveData<List<AppointmentModel>>。在我的 onViewCreated() 回调中,我 运行

String barberName = mBarberViewModel.getBarberFullName();
        mTxtv_barberName.setText(barberName);

但是,mMasterAppointments 始终为空,因此它只是 returns mBarberFullName 的默认值,即 String.

但是,如果我要 运行 以下代码,在相同的 onViewCreated() 中,我会得到所需的结果,其中 textview 已更新为所需理发师的全名。

  mBarberViewModel.getAllAppointments().observe(getViewLifecycleOwner(), am -> {
            if (am.isEmpty()) {
                Log.d(TAG, "No barber.");
                return;
            }
            String barberGreeting;
            barberGreeting = am.get(0).bFirstName;
            barberGreeting = barberGreeting.concat(" " + am.get(0).bLastName);
            mTxtv_barberName.setText(barberGreeting);
        });

getAllAppointments returns mMasterAppointments 的观察者位于我的 ViewModel 中。

虽然在 onViewCreated() 中调用了 getAllAppointmentsgetBarberFullName,但其中一个可以访问 mMasterAppointments 的挂起值,而另一个则不能。为什么?

我不想在我的 Fragments onViewCreated 回调中执行逻辑,那么我如何才能等待 ViewModel 的 getBarberFullName() 中的未决 mMasterApointmentDataLiveDataViewModel 中是否有工具可以帮助我解决这种情况?

使用 LiveData 的 Transformations class

when you need to perform calculations, display only a subset of the data, or change the rendition of the data.

首先在viewmdoel中为BarberFullName添加一个新的String LiveData,并赋予其将源LiveData mMasterAppointments转换(映射)为所需String的值:

val fullBarberName: LiveData<String> = Transformations.map(mMasterAppointments) { am ->
         " ${am[0].bFirstName} ${am.get(0).bLastName}" 
}

现在您可以在您的片段中观察这个 String LiveData,就像您在第二个片段中那样。

请注意,我提供的代码是使用 Kotlin 编写的,我现在正在使用它。希望你能明白。