我有MVP模式显示的项目列表。视图是一项活动(a.k.a。ItemsList
)。我想显示下一个活动(也是MVP' ed,a.k.a。ItemDetails
),其中包含点击ItemsList
项目的详细信息。
ItemsList
的模型由Repository提供数据。实际上它是RMVP。它看起来像这样:
|->Model<->Presenter<->View [ItemsList]
Repository<-|
|->Model<->Presenter<->View [ItemDetails]
因此,ItemsList
的模型已经确切地知道单击了哪个模型项,因此我可以立即将其从ItemsList
传递到ItemDetails
,而无需再次从存储库中获取数据/从数据到模型的映射/为ItemDetails
等制作新模型
我应该如何在MVP中的活动之间传递数据(例如,点击了哪个项目?)
解决方案1
使用Intent(similar to what is discussed here)传递这些数据但是......然后如何处理这些数据?你可以在活动(视图)中从Intent解压缩它,而你应该在MVP的另一端,即在模型中。您将它从View to the Presenter传递给Model?
但是ItemDetails
中的模型不是从MVP&#34;的缺点创建的。 (来自Repository)但是来自MVP&#34; (来自Presenter)。
解决方案2
仅将点击的项目的ID传递给ItemDetails
视图(类似于android10/Android-CleanArchitecture在UserDetailsActivity中使用字段private int userId
建议的内容;这也是googlecodelabs' NoteDetailPresenter使用的内容)
但是可能存在问题,因为我可能有两个Repository实现:
ItemDetails
视图(但它似乎过度设计),类似于android10/Android-CleanArchitecture在UserDetailsActivity中提出的字段private int userId;
ItemsList
提取的列表答案 0 :(得分:1)
最近,我在我的应用程序中也使用了MVP。我发现了同样的问题,并使用intent将数据从ItemListActivity传递给ItemDetailActivity。我通过了实现Parcelable接口的模型类,没有发现任何问题,它工作正常。
原因是:在ItemDetailActivity中,我们必须从您的案例中的数据库或存储库中获取数据,这会增加应用程序中的一个操作。
在ItemlistActivity中,您将只执行单个操作来获取所有数据。但是,如果将ItemListActivity中的数据传递给ItemDetailActivity,则只需在ItemDetailActivity中获取数据而无需任何特殊操作。
我建议你去寻求解决方案1.
答案 1 :(得分:0)
在一个应用程序中,我使用了这两种方法和第三种方法。 在第三个选项中,我使用应用程序级缓存并将对象填充到那里并将缓存密钥传递给新意图。这是没有repo缓存的解决方案2的变体。我知道我只需要临时缓存中的项目;因此,从缓存中删除项目以防止内存泄漏非常重要。 我通常喜欢第二个解决方案,因为我不必使对象可以分配(可能有点懒惰)。 我没有注意到任何方法的性能差异。
最后,我在传递视图模型时确定了解决方案1(我的所有视图模型都可以使用)。使用domian模型时的解决方案2(因为它们已经在数据库中,所以它更容易传递密钥)。如果domian对象处于临时状态(具有尚未持久化的新域对象或状态可能与数据库不一致的域对象,即更改尚未持久且活动因某种原因而被暂停),则具有缓存的解决方案2 < / p>
答案 2 :(得分:0)
如果您使用的是视图优先导航,我认为您可以创建自己的presenter-layer bundle(或类似的东西)并将其意图发送到新的Activity。然后,新的Activity将提取此包并将其传递给演示者。
答案 3 :(得分:0)
此外,我认为还有第三个考虑因素 - 在MVP中,您模型正在对问题域进行建模,并且应该能够存在,无论选择何种< strong> V 和 P 。如果您的ItemDetails和ItemList属于同一个问题域,那么您的模型可能会对它们进行建模,而您实际上要做的就是出现数据以两种不同的方式(一种作为列表,一种作为细节)。
在这种情况下,共享模型可能是可行的,并且只有不同的演示和查看层。在这种情况下,一旦你的细节传回给你的模型,这只是附加一个新的演示者以呈现所选择的ItemDetail的情况。
答案 4 :(得分:0)
单击某个项目时,您应该将该信息传递给演示者,演示者将决定需要将哪些数据发送到哪个活动。然后,您的演示者可以将数据和目标活动类打包成一个intent,并将其传递回原始视图。例如,像navigateToActivity(Intent i)。原始视图以给定的意图开始活动。这允许原始视图对于下一个屏幕需要的内容是愚蠢的(因为可能有多个选项)。业务逻辑是演示者的工作。
然后,当演示者初始化时,新视图的演示者将解包与意图一起发送的数据,正如Kishan所说。在知道如何处理意图中的数据方面,目标视图也是愚蠢的。