Как передать данные из презентатора родительского представления в презентатор дочернего представления? - PullRequest
0 голосов
/ 23 апреля 2019

Я использую шаблоны MVP в Android. И структура выглядит следующим образом.

Activity - Presenter
    |
Fragment
    |
CustomView
    |
  views

Таким образом, когда докладчик получает данные из сети, он напрямую передает данные во фрагмент, а данные передачи фрагмента - в пользовательское представление, а данные пользовательского представления - в представления.

Я не уверен, как передать данные, используемые в представлениях, из действий с шаблонами MVP. Если я создаю докладчиков для каждого фрагмента, пользовательских представлений и представлений, то как я могу передавать данные от докладчика действия другим докладчикам? Кто-нибудь может помочь мне с примерами?

1 Ответ

1 голос
/ 11 мая 2019

Чтобы дать более конкретный ответ на ваш вопрос, нужно привести конкретный пример.Каждое решение действует в контексте .Я дам пару способов сделать это.Выберите тот, который соответствует вашей проблеме.

Очень важной частью MVP является Модель .Насколько мне известно, термин Model стал популярным в программировании с выпуском статьи Thing Model View Editor , которая была позже усовершенствована и переименована в MVC,

Определение понятия Модель из этого документа:

A Модель является активным представлением абстракции в виде данных в вычислительной системе

Моделей представлены в компьютере как набор данных вместе с методами , необходимыми для обработки этих данных.

Со временем и опытом людиобнаружены и указаны различные типы моделей.

Вот некоторые из них:

MVP , поскольку она происходит от MVC, выполняет два основных раздела обязанностей: Модель ( абстракция, представляющая понятия ) и Презентация ( Просмотр и презентация для визуализации Модель ).

Поскольку мы разделили Модель от Презентация , мы можем иметь несколько Представлений , которые показывают одинаковые Модель различными способами.Примером этого является Модель , которая представляет Статистические данные , которые могут быть показаны различными способами: круговая диаграмма, гистограмма и т. Д.В этом примере Модель статистических данных представляет собой Модель домена .

В приведенном выше примере Модель , вероятно, будет разделена между двумя парами View-Presenter , PieChart и BarChart .Если вы используете шаблон Observer , когда одна из пар View-Presenter обновит StatisticalModel , этовызовет измененные события, и обе пары View-Presenter получат уведомления об этом изменении и обновлении.

Иногда приложению требуется ApplicationModel .Эта модель может использоваться несколькими парами представления-представления .Давайте рассмотрим пример verfy упрощенный .

Допустим, у нас есть приложение для просмотра файлов, такое как Windows Explorer.Этот графический интерфейс приложения состоит из двух основных частей: левая панель, отображающая дерево папок, и средняя панель File-Folder.Когда папка выбрана на левой панели дерева папок, файлы и папки из выбранной папки должны отображаться на средней панели.Мы можем сделать это, определив ApplicationModel , который будет захватывать и представлять вышеуказанную логику и совместно использоваться обеими парами Просмотр-представление длялевая и средняя панели.

Примечание: я опущу детали только для примера и напишу меньше кода

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 является частью Model и является Application Model .Поскольку оно является общим и его время жизни такое же, как у приложения (оно существует до тех пор, пока приложение работает), оно будет удерживать состояние. Представления и Представители создаются и уничтожаются, но этот класс будет существовать и удерживать состояние, так что при появлении нового Просмотр и / или Ведущий создан, он может проверять это состояние и что-то делать.

В моем опыте люди действительно концентрируются наПредставлений и докладчиков больше, пока они должны работать над своими моделями .Перонально я использую Models много, поскольку это делает вещи чище и приложение легче понять.

Конечно, использование моделей не всегда работает, поэтому, когда они не работают, вы можете использовать сообщения Имея один Ведущий отправка сообщений другим.Вот пример с тем же приложением File Browser.

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);
       }
    }
}

В зависимости от вашего конкретного случая, если вы можете создать красивую Модель , либо домен, приложениеили презентация, сделай это.Поделитесь этим Модель , создавая таким образом зависимость от Модель от Presenters вместосоздания зависимости между Presenters .Таким образом, у вас есть слабая связь между докладчиками , и вы можете изменить их намного проще

Если вы не можете использовать Модель , используйте Сообщения .Это хороший способ отделить докладчиков , создав протокол сообщений, используемых для связи.

Проверка эта статья об использовании сообщений для совместной работы компонентов.

Также есть несколько хороших статей об архитектурах графического интерфейса:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...