FreshMvvm icon indicating copy to clipboard operation
FreshMvvm copied to clipboard

RemoveFromNavigation and then popping PageModel causes ReverseInit being called on removed FreshBasePageModel, instead of the one being popped

Open theberserker opened this issue 9 years ago • 3 comments

Let's say we have FirstPageModel and SecondPageModel in the current page model navigation stack and we are on ThirdPageModel. Then if we call:

CoreMethods.RemoveFromNavigation<SecondPageModel>();
await CoreMethods.PopPageModel(data);

the FirstPage and FirstPageModel (at PopPageModel call) are resolved correctly, but I would expect that the ReverseInit is called on FirstPageModel, which doesn't happen. Instead it is called on SecondPageModel, that was removed in the RemoveFromNavigation call.

The problem lies in RemoveFromNavigation<T>() implementation that does not rewire the link of PreviousPageModel. Below is the proposed solution which works for us. It keeps the track of the next page model as we are looking for a match in linked list of previous page models. As the match is found, it links the previous and next node of removed one.

/// <summary>
/// Removes specific page/pagemodel from navigation
/// </summary>
public void RemoveFromNavigation<TPageModel> (bool removeAll = false) where TPageModel : FreshBasePageModel
{
    FreshBasePageModel nextPageModel = null;
    foreach (var page in this._currentPage.Navigation.NavigationStack.Reverse().ToList())
    {
        if (page.BindingContext is TPageModel) 
        {
            page.GetModel()?.RaisePageWasPopped ();
            this._currentPage.Navigation.RemovePage (page);

            bool isPreviousPageModelMatch = typeof(TPageModel) == nextPageModel?.PreviousPageModel?.GetType();
            if (isPreviousPageModelMatch)
            {
                nextPageModel.PreviousPageModel = nextPageModel.PreviousPageModel.PreviousPageModel;
            }
            if (!removeAll)
                break;
        }
        nextPageModel = nextPageModel == null ? _currentPageModel : nextPageModel.PreviousPageModel;
    }
}

Please let me know what do you think. If you agree with the solution I can send a pull request.

theberserker avatar Sep 21 '16 14:09 theberserker

@theberserker Great to see you using the RemoveFromNavigation. That looks like a good solution, I would accept a PR. Thanks

rid00z avatar Sep 22 '16 00:09 rid00z

Yes, RemoveFromNavigation seems really good approach to return few steps back and pop only one page model instead of multiple of them.

So, opened a pull request here: https://github.com/rid00z/FreshMvvm/pull/105

theberserker avatar Sep 22 '16 13:09 theberserker

I'm facing this issue as well and still have not found a way of fixing it. I am trying to pass parameters so I really need the reverseInit to work properly.. By setting PreviousPageModel to null, I end up in the right page but reverseInit is not called. Any suggestions ? @theberserker @rid00z

Stratosf avatar Jan 11 '21 13:01 Stratosf