【问题标题】:MVVM + DatabindingMVVM + 数据绑定
【发布时间】:2018-06-27 06:10:56
【问题描述】:

假设我有一个天气应用程序,我从数据提供者那里获取数据并将其保存在我的本地数据库中。现在我有一个Repository 类,它的工作是根据特定条件从API 或本地数据库中获取数据。我有一个设置页面,用户选择以°F 显示温度,以公里为单位显示距离。我从 API 获得的数据是温度的°C 和距离的 mi。我的View 请求ViewModelRepository 获取数据。 Repository 获取数据并返回一个名为 WeatherData 的模型。现在我拥有的数据以°C 和 mi 为单位。使用DataBinding 在我的布局文件中导入一个Util 类是否是个好主意,其中包含根据用户在设置中选择的转换这些单位的帮助方法?或者WeatherData 中是否应该有方法可以转换数据并使用数据绑定显示在视图中?还是有其他人以正确的方式做到这一点?

【问题讨论】:

  • 致投反对票的人:感谢您投反对票。正因为如此,我才知道我的问题不“值得”,但如果您在评论中说明拒绝投票的原因,它会对我有更多帮助。您可能投了反对票,因为: 1. 我的理解很差。 2:问题不清楚 3:这是一个愚蠢的问题。 4:或其他原因。这将仍然是一个谜,我将永远无法改进我未来的问题。 :(。

标签: android mvvm android-databinding


【解决方案1】:

这是一个有趣的问题,可能会有不同的答案,但我会就此事发表我的看法。

查看 ViewModel 的一种方法是将其视为视图的“模型”。通过这种方式,您可以确定您的视图将非常精简和虚拟,这是理想的,因为它们可能很难(即使不是不可能)进行测试。由于 VM 也是视图和模型之间的层,因此它是进行数据和类型转换的理想场所。好处包括可测试性(正如我所说,很难在 XML 中验证转换逻辑)和更好的可维护性(如果由于某种原因您将来必须更改视图)。

要考虑的另一点是干净的架构。在干净的架构中,依赖关系是向内的。上层模型应该与下层模型相互映射。在您的情况下,Repository 已经达到了提供WeatherData 的目的,它不应该关心数据将如何在上层使用。

所以为了回答你的问题,我认为它应该在ViewModel 中,或者如果你想在不同视图中的多次转换的情况下进一步解耦,你的域层和 ViewModel 之间的 Converter 层。

【讨论】:

  • 我喜欢解耦转换部分的想法。因为我还没有真正进入单元测试。我刚刚开始探索它,我有一个问题,我不能在Utils 类中测试那些帮助方法的输出,即使在 XML 中使用它们?我可以模拟输入数据并在对这些方法进行单元测试时将其传递。
  • 如果我正确理解您的问题,是的,您可以独立测试您的 Utils。但是您无法验证这些函数是否在您的视图中正确使用,因为您无法测试它们。
  • 知道了。谢谢你。我会再等一天,如果我没有得到更好的答案,我会标记你的答案。
【解决方案2】:

因此,您要做的是根据您的设置,您必须显示°C/°F 和 mi/km。

您可以在模型类WeatherData中拥有转换逻辑

喜欢,

class WeatherData{

    private float degrees;

    public float getCelsius(){
        //conversion
    }

    public float getFahrenheit(){
        //conversion
    }

    private float km;

    public float getKm(){
        //conversion
    }

    public float getMiles(){
        //conversion
    }

} 

在你的视图模型中你可以有boolean celsius,km;这样的标志

在布局中你可以定义这三个变量。

    <data>
        <variable
            name="celsius"
            type="Boolean"/>
        <variable
            name="km"
            type="Boolean"/>
        <variable
            name="data"
            type="WeatherData"/>
    </data>
    <TextView
        android:id="@+id/tv_distance"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@{km?data.km:data.miles}" />
    <TextView
        android:id="@+id/tv_temperature"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@{celsius?data.celsius:data.fahrenheit}"
        />

【讨论】:

    猜你喜欢
    • 2013-01-07
    • 2015-07-15
    • 2015-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-17
    • 2012-10-29
    相关资源
    最近更新 更多