OnNavigatedTo или Initialize слишком поздно для привязки - PullRequest
0 голосов
/ 15 февраля 2020

Я новичок в Призме с Xamarin.Forms. Я реализовал подход ViewModel, используя классы Navigation и Commanding. Это работает просто отлично, но есть одна вещь, которую я не понимаю. Если для AutowireViewModel установлено значение true, ViewModelLocator автоматически заполняет BindingContext для меня, и это приятно. Порядок вещей не то, что я ожидал. Сначала запускается привязка для свойств в представлении огня, а затем запускается OnNavigatedTo. Это означает, что моя инициализация свойств уже завершена к тому времени, как я получу параметры в представлении. Я могу решить эту проблему, выполнив RaisePropertyChanged. Это приводит к следующему:

  1. Я вынужден написать RaisePropertyChanged для каждого свойства в ViewModel, которое я хочу видеть в представлении с новыми данными.
  2. Все привязки срабатывают два раза , Для быстрых вещей это не проблема, но некоторые медленнее.
  3. Данные обновляются после того, как представление стало видимым. Не беспокоит, но было бы лучше показать готовый вид с его данными сразу.
  4. Все свойства должны иметь возможность обрабатывать нулевые ссылки.

Есть ли способ инициализации данные в ViewModel до того, как сработает привязка?

1 Ответ

0 голосов
/ 23 февраля 2020

На самом деле Prism для Xamarin.Forms давно поддерживает инициализацию ваших ViewModels до того, как View будет помещен в NavigationStack. Тем не менее, есть порядок операций, который должен быть принят во внимание. Например, мы не можем выполнить несколько операций над ViewModel, а затем присоединить его к View.

Порядок, в котором выполняются действия, выглядит следующим образом:

  • View Создано (все в ctor представления выполняется)
  • Если вы специально прикрепили свойство ViewModelLocator.AutowireViewModel, это разрешит ViewModel как часть ctor
  • Если вы специально не отключили AutoWire ViewModelLocator, служба навигации установит его для вас (после завершения ctor)
  • Затем NavigationService вызовет IAutoInitialize / IInitialize / InitializeAsyn c (для Prism 7.2 + ... INavigatingAware.OnNavigatingTo in более старые версии Prism)
  • Затем NavigationService помещает sh страницу в стек навигации (обратите внимание, что это может или не может быть видно пользователю, так как дополнительные страницы могут быть добавлены первыми при глубокой ссылке )
  • Затем NavigationService вызовет OnNavigate dFrom / OnNavigatedTo (именно здесь люди часто сообщают о видимой задержке из-за обновлений привязки.

Для подавляющего числа сценариев ios, если вы правильно инициализировали вашу ViewModel, этот процесс работает точно так же, как вы нужно. Если у вас есть некоторый крайний случай, когда вам абсолютно необходимо убедиться, что ViewModel инициализируется до того, как он установлен, вам придется обработать это вручную.

public partial class ViewA : ContentPage, IInitialize
{
    private ViewAViewModel ViewModel { get; }

    public ViewA(ViewAViewModel viewModel)
    {
        ViewModel = viewModel;

        // Explicitly Opt Out of Autowiring
        ViewModelLocator.SetAutowireViewModel(this, false);

        InitializeComponent();
    }

    public void Initialize(INavigationParameters parameters)
    {
        ViewModel.Initialize(parameters);
        BindingContext = ViewModel;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...