如何将数据从父视图的演示者传递到子视图的演示者?
How to pass data from parent view's presenter to child view's presenter?
我在 Android 中使用 MVP 模式。结构如下所示。
Activity - Presenter
|
Fragment
|
CustomView
|
views
所以当presenter从网络获取数据时,直接传数据给fragment,fragment传数据给自定义视图,自定义视图传数据给视图。
我不确定如何使用 MVP 模式传递来自 activity 的视图中使用的数据。如果我为每个片段、自定义视图和视图创建演示者,那么如何将数据从 activity 的演示者传递给其他演示者?
谁能帮我举个例子?
为了更具体地回答您的问题,您需要举一个具体的例子。每个解决方案在 context 中都是有效的。我将提供几种方法供您执行此操作。选择适合您的问题。
MVP 非常重要的部分是 模型。据我所知,术语 Model 随着论文 Thing Model View Editor 的发布而在编程中变得流行,后来被提炼和重命名为 MVC。
论文中一个模型的概念定义是:
A Model is an active representation of an abstraction in the form of
data in a computing system
The Models are represented in the computer as a collection of data
together with the methods necessary to process these data.
随着时间和经验的积累,人们发现并指定了不同类型的模型。
以下是其中的一些:
- Domain Model
- 应用模型(阅读this article了解更多信息)
- Presentation Model
MVP,由于是从MVC派生出来的,所以做了两大职责划分:Model(表示概念的抽象)和Presentation(View and Presenter 可视化 模型).
因为我们已经将Model从Presentation[中分离出来了=171=],我们可以有多个 Views 显示相同的 Model 不同的方式。一个例子是 Model 表示 Statistical Data 可以以不同的方式显示:饼图、条形图等。在此示例中,统计数据模型 是 领域模型.
在上面的例子中,模型可能会在两个[之间共享=284=]对,PieChart和条形图。如果您使用 Observer pattern,当 View-Presenter 对之一 更新 StatisticalModel,它会引发变化的事件,View-Presenter对都会收到此更改和更新的通知。
有时应用程序需要 ApplicationModel。该模型可以在不同的 View-Presentation 对 之间共享。我们来看一个 verfy 简化的 示例。
假设我们有一个文件浏览器应用程序,例如 Windows Explorer。该应用程序的 GUI 有两个主要部分:显示文件夹的 Tree 的左侧面板和中间的 File-Folder 面板。在左侧文件夹树面板中选择文件夹时,所选文件夹中的文件和文件夹必须显示在中间面板中。我们可以通过定义一个 ApplicationModel 来做到这一点,它将捕获和表示上述逻辑并在 [=57= 之间共享]View-Presentation 对 用于左侧和中间面板。
注意:我将省略细节以简化示例并减少代码
public class ApplicationState {
// singleton, it's evil I know,
// but it's the simplest way without DI or ServiceLocator
private static ApplicationState mInstance = new ApplicationState();
public static ApplicationState getInstance() { return mInstance; }
private Folder mSelectedFolder;
public bool hasSelectedFolder() { return mSelectedFolder != null; }
public Folder getSelectedFolder() { return mSelectedFolder; }
public Folder setSelectedFolder(Folder f) {
mSelectedFolder = f;
RaiseSelectedFolderChangedEvent();
}
// method for registering listeners, raising events etc.
}
public class FoldersTreeViewPresenter {
private ApplicationState mApplicationState;
public void onSelectFolder(FolderView view) {
// select the folder in the view
mApplicationState.setSelectedFolder(view.Folder);
}
}
public class FilesFoldersViewPresenter : ApplicationStateListener {
private ApplicationState mApplicationState;
public FilesFoldersViewPresenter() {
// you can use service locator, dependency injection, whatever
mApplicationState = ApplicationState.getInstance();
mApplicationState.addEventListener(this);
}
private void getFilesAndFoldersFromFileSystem(Folder folder) {
// get from fs
// fill views with them etc.
}
private void clearView() {
// clear the panel
}
public void onApplicationStateChanged() {
if(mApplicationState.hasSelectedFolder()){
getFilesAndFoldersFromFileSystem(mApplicationState.getSelectedFolder());
}
else {
clearView();
}
}
}
在这个例子中,我们创建了一个共享对象来表示应用程序状态和逻辑,我们的应用程序有一个可以更改的选择。在这种情况下,ApplicationState class 是 Model 的一部分 并且是一个 应用程序模型。因为它是共享的并且它的生命周期与应用程序相同(只要应用程序是 运行 它就存在)它将保持状态。 Views 和 Presenters 被创建和销毁,但这class 将存在并保持状态,因此当一个新的 View and/or Presenter 已创建,它可以检查此状态并执行某些操作。
根据我的经验,人们确实更多地关注 Views 和 Presenter,而他们应该专注于 Models。我个人经常使用 Models,因为它让事情变得更清晰,应用程序更容易理解。
当然,使用 Models 并不总是有效,所以当它们不起作用时,您可以使用 messaging,有一个 Presenter 向其他人发送消息。这是使用相同文件浏览器应用程序的示例。
public class MessageBus {
// static this time, you can use DI or ServiceLocator with interface
public static void sendMessage(object m) { }
public static void registerListener(MessageListener listener) { }
}
public class FoldersTreeViewPresenter {
public void onSelectFolder(FolderView view) {
// select the folder in the view
MessageBus.sendMessage(new FolderSelected(view.Folder));
}
}
public class FilesFoldersViewPresenter : MessageListener {
public FilesFoldersViewPresenter() {
MessageBus.addListener(this);
}
private void getFilesAndFoldersFromFileSystem(Folder folder) {
// get from fs
// fill views with them etc.
}
public void onMessage(object m) {
if(m instanceof FolderSelected) {
FolderSelected folderSelectedMessage = (FolderSelected)m;
getFilesAndFoldersFromFileSystem(folderSelectedMessage.Folder);
}
}
}
根据您的具体情况,如果您可以创建一个不错的 模型,无论是域、应用程序还是演示文稿,都可以创建。分享这个 Model 从而创建对 Model 的依赖从 Presenters 而不是创建依赖关系 between Presenters 。这样你就有了松耦合ng 在 Presenters 之间,您可以更轻松地更改它们
如果您不能使用 Model,请使用 Messages。通过创建 protocol[=171= 来解耦 Presenters 是一种很好的方式] 用于通信的消息。
查看 this 有关使用消息进行组件间协作的文章。
这里还有一些关于 GUI 架构的好文章:
我在 Android 中使用 MVP 模式。结构如下所示。
Activity - Presenter
|
Fragment
|
CustomView
|
views
所以当presenter从网络获取数据时,直接传数据给fragment,fragment传数据给自定义视图,自定义视图传数据给视图。
我不确定如何使用 MVP 模式传递来自 activity 的视图中使用的数据。如果我为每个片段、自定义视图和视图创建演示者,那么如何将数据从 activity 的演示者传递给其他演示者? 谁能帮我举个例子?
为了更具体地回答您的问题,您需要举一个具体的例子。每个解决方案在 context 中都是有效的。我将提供几种方法供您执行此操作。选择适合您的问题。
MVP 非常重要的部分是 模型。据我所知,术语 Model 随着论文 Thing Model View Editor 的发布而在编程中变得流行,后来被提炼和重命名为 MVC。
论文中一个模型的概念定义是:
A Model is an active representation of an abstraction in the form of data in a computing system
The Models are represented in the computer as a collection of data together with the methods necessary to process these data.
随着时间和经验的积累,人们发现并指定了不同类型的模型。
以下是其中的一些:
- Domain Model
- 应用模型(阅读this article了解更多信息)
- Presentation Model
MVP,由于是从MVC派生出来的,所以做了两大职责划分:Model(表示概念的抽象)和Presentation(View and Presenter 可视化 模型).
因为我们已经将Model从Presentation[中分离出来了=171=],我们可以有多个 Views 显示相同的 Model 不同的方式。一个例子是 Model 表示 Statistical Data 可以以不同的方式显示:饼图、条形图等。在此示例中,统计数据模型 是 领域模型.
在上面的例子中,模型可能会在两个[之间共享=284=]对,PieChart和条形图。如果您使用 Observer pattern,当 View-Presenter 对之一 更新 StatisticalModel,它会引发变化的事件,View-Presenter对都会收到此更改和更新的通知。
有时应用程序需要 ApplicationModel。该模型可以在不同的 View-Presentation 对 之间共享。我们来看一个 verfy 简化的 示例。
假设我们有一个文件浏览器应用程序,例如 Windows Explorer。该应用程序的 GUI 有两个主要部分:显示文件夹的 Tree 的左侧面板和中间的 File-Folder 面板。在左侧文件夹树面板中选择文件夹时,所选文件夹中的文件和文件夹必须显示在中间面板中。我们可以通过定义一个 ApplicationModel 来做到这一点,它将捕获和表示上述逻辑并在 [=57= 之间共享]View-Presentation 对 用于左侧和中间面板。
注意:我将省略细节以简化示例并减少代码
public class ApplicationState {
// singleton, it's evil I know,
// but it's the simplest way without DI or ServiceLocator
private static ApplicationState mInstance = new ApplicationState();
public static ApplicationState getInstance() { return mInstance; }
private Folder mSelectedFolder;
public bool hasSelectedFolder() { return mSelectedFolder != null; }
public Folder getSelectedFolder() { return mSelectedFolder; }
public Folder setSelectedFolder(Folder f) {
mSelectedFolder = f;
RaiseSelectedFolderChangedEvent();
}
// method for registering listeners, raising events etc.
}
public class FoldersTreeViewPresenter {
private ApplicationState mApplicationState;
public void onSelectFolder(FolderView view) {
// select the folder in the view
mApplicationState.setSelectedFolder(view.Folder);
}
}
public class FilesFoldersViewPresenter : ApplicationStateListener {
private ApplicationState mApplicationState;
public FilesFoldersViewPresenter() {
// you can use service locator, dependency injection, whatever
mApplicationState = ApplicationState.getInstance();
mApplicationState.addEventListener(this);
}
private void getFilesAndFoldersFromFileSystem(Folder folder) {
// get from fs
// fill views with them etc.
}
private void clearView() {
// clear the panel
}
public void onApplicationStateChanged() {
if(mApplicationState.hasSelectedFolder()){
getFilesAndFoldersFromFileSystem(mApplicationState.getSelectedFolder());
}
else {
clearView();
}
}
}
在这个例子中,我们创建了一个共享对象来表示应用程序状态和逻辑,我们的应用程序有一个可以更改的选择。在这种情况下,ApplicationState class 是 Model 的一部分 并且是一个 应用程序模型。因为它是共享的并且它的生命周期与应用程序相同(只要应用程序是 运行 它就存在)它将保持状态。 Views 和 Presenters 被创建和销毁,但这class 将存在并保持状态,因此当一个新的 View and/or Presenter 已创建,它可以检查此状态并执行某些操作。
根据我的经验,人们确实更多地关注 Views 和 Presenter,而他们应该专注于 Models。我个人经常使用 Models,因为它让事情变得更清晰,应用程序更容易理解。
当然,使用 Models 并不总是有效,所以当它们不起作用时,您可以使用 messaging,有一个 Presenter 向其他人发送消息。这是使用相同文件浏览器应用程序的示例。
public class MessageBus {
// static this time, you can use DI or ServiceLocator with interface
public static void sendMessage(object m) { }
public static void registerListener(MessageListener listener) { }
}
public class FoldersTreeViewPresenter {
public void onSelectFolder(FolderView view) {
// select the folder in the view
MessageBus.sendMessage(new FolderSelected(view.Folder));
}
}
public class FilesFoldersViewPresenter : MessageListener {
public FilesFoldersViewPresenter() {
MessageBus.addListener(this);
}
private void getFilesAndFoldersFromFileSystem(Folder folder) {
// get from fs
// fill views with them etc.
}
public void onMessage(object m) {
if(m instanceof FolderSelected) {
FolderSelected folderSelectedMessage = (FolderSelected)m;
getFilesAndFoldersFromFileSystem(folderSelectedMessage.Folder);
}
}
}
根据您的具体情况,如果您可以创建一个不错的 模型,无论是域、应用程序还是演示文稿,都可以创建。分享这个 Model 从而创建对 Model 的依赖从 Presenters 而不是创建依赖关系 between Presenters 。这样你就有了松耦合ng 在 Presenters 之间,您可以更轻松地更改它们
如果您不能使用 Model,请使用 Messages。通过创建 protocol[=171= 来解耦 Presenters 是一种很好的方式] 用于通信的消息。
查看 this 有关使用消息进行组件间协作的文章。
这里还有一些关于 GUI 架构的好文章: