2016-11-24 8 views
1

私はタイトルの言葉がどれほど優れているかわからなかったので、私は自分の頭に浮かんだ解決策を見つけました。ページを開くたびに新しいViewModelを使用する

ここに問題があります。私はリストを持っているページを持っていて、リストの各アイテムは詳細ページを(クリックで)開きます。しかし、VMは再利用されているため、いくつかの問題が発生します。

  • 詳細ページを開くときに

    • 前のデータは、私はときにページが開いて特定の値に設定する特定のプロパティを必要とするが、VMが再利用されているので、それはすべて保持一瞬のために見ることができます前の詳細の値とこれは私の論理を駄目にする。

    このUWPアプリ。私は、ページ間を移動するためにTemplate10フレームワークのNavigationServiceを使用しています。

    メインページのViewModel

    public class MainPageViewModel : ViewModelBase { 
        private List<MangaItem> _mangaList; 
        public List<MangaItem> mangaList { 
         get { return _mangaList; } 
         set { Set(ref _mangaList, value); } 
        } 
    
        private string _mainSearchText; 
        public string mainSearchText { 
         get { return _mainSearchText; } 
         set { Set(ref _mainSearchText, value); } 
        } 
    
        public MainPageViewModel() { 
         _mangaList = new List<MangaItem>(); 
         mangaList = new List<MangaItem>(); 
    
         Initialize(); 
        } 
    
        private async void Initialize() { 
         mangaList = await MangaListGet.GetListAsync(); 
        } 
    
        public async void MainSearchSubmitted() { 
         mangaList = await MangaListGet.GetListAsync(_mainSearchText); 
        } 
    
        public void MangaSelected(object sender, ItemClickEventArgs e) { 
         var mangaItem = (MangaItem)e.ClickedItem; 
         NavigationService.Navigate(typeof(Views.MangaDetail), mangaItem.id); 
        } 
    } 
    

    かつ詳細ページのViewModelは

    class MangaDetailViewModel : ViewModelBase { 
    
        private MangaItem _mangaDetail; 
        public MangaItem mangaDetail { 
         get { return _mangaDetail; } 
         set { Set(ref _mangaDetail, value); } 
        } 
    
        private string _mangaId; 
    
        public override async Task OnNavigatedToAsync(object parameter, NavigationMode mode, IDictionary<string, object> suspensionState) { 
         _mangaId = parameter as string; 
         Initialize(); 
    
         await Task.CompletedTask; 
        } 
    
        private async void Initialize() { 
         mangaDetail = await MangaDetailGet.GetAsync(_mangaId); 
        } 
    
        public void ChapterSelected(object sender, ItemClickEventArgs e) { 
         var _chapterId = (ChapterListItem)e.ClickedItem; 
         NavigationService.Navigate(typeof(Views.ChapterPage), _chapterId.id); 
        } 
    } 
    

    このコードは、最初の問題は一瞬のために以前にロードされたデータを表示している示しています。必要に応じて、他の問題を紹介するコードを追加しますが、今のところ本当に適切かどうかはわかりません。おそらく私の全体の論理に欠陥があるとか、何かがあると思っています。

    EDIT:VMがxmlns:vm="using:MangaReader.ViewModels"ある

    <Page.DataContext> 
        <vm:ChapterPageViewModel x:Name="ViewModel" /> 
    </Page.DataContext> 
    

  • +1

    NavigationCacheModeを使用する場合、同じ問題が発生しました。私は古いデータを取り除き、 'OnNavigatedTo'でページを初期化します。新しいデータを読み込む前に 'DataContext = null;'を削除し、完了したらそれを再接続してください。 –

    +0

    あなたは私のコードでこれを行う方法をより具体的に教えてください。ありがとう。 – rancor1223

    +0

    ページをビューモデルにバインドする方法がわかりません。 DataContextをViewModelに設定している場合は、バインド 'DataContext = null;を削除して、ViewModelの新しいデータを設定し、' DataContext = mangaDetailViewModel'で再接続します。 DetailPageの 'OnNavigatedTo'でこれを行います。 –

    答えて

    0

    Template10のドキュメントでは、デフォルトではNavigationCacheModeが無効になっていると記載されていますが、テンプレートの例ではそうではありません。これはView C#コード(.xaml.csファイル)で設定されます。

    .xaml.cs今すぐ

    namespace MangaReader.Views { 
        public sealed partial class MangaDetail : Page { 
         public MangaDetail() { 
          InitializeComponent(); 
          //NavigationCacheMode = Windows.UI.Xaml.Navigation.NavigationCacheMode.Enabled; //this was set by default 
          NavigationCacheMode = Windows.UI.Xaml.Navigation.NavigationCacheMode.Disabled; 
         } 
        } 
    } 
    

    ファイル、新しいViewModelには、あなたがこのページにアクセスするたびに作成されます。

    1

    別の解決方法は、依存関係注入を処理することを目的としていますが、ニーズに容易に対応できるBootstrapper.ResolveforPage()を使用することです。このように:

    [Bindable] 
    sealed partial class App : BootStrapper 
    { 
        static ViewModels.DetailPageViewModel _reusedDetailPageViewModel; 
        public override INavigable ResolveForPage(Page page, NavigationService navigationService) 
        { 
         if (page.GetType() == typeof(Views.DetailPage)) 
         { 
          if (_reusedDetailPageViewModel == null) 
          { 
           _reusedDetailPageViewModel = new ViewModels.DetailPageViewModel(); 
          } 
          return _reusedDetailPageViewModel; 
         } 
         else 
         { 
          return null; 
         } 
        } 
    } 
    

    NavigationServiceはこれを他のビューモデルと同じように扱います。つまり、OnNavTo()と他のナビゲーションオーバーライドを呼び出すことになります。

    幸運のベスト。

    +0

    私のソリューションは、文字通り、あなたが求めていたことの反対をしました。 –

    関連する問題