子视图模型更新时如何更新父视图模型

TwanWV

在我的第一个视图模型(重命名为MainViewModel)中,我有一个ActionViewModels列表。在我的xaml中,我有一个绑定到列表的列表框,在该列表框中,我有一个模板,该模板绑定到ActionViewModel的属性。

到目前为止,一切都很好。当选择我导航到ActionViewModel并与它通过该ID的listItems中的一个。ActionViewModel从内存中的静态列表中检索信息,MainViewModel也从该列表中检索信息以创建actionviewmodels列表。

到目前为止还算不错,我可以编辑属性,所有绑定都可以正常工作,我也很高兴。通过单击保存按钮,信息将被收集并存储在静态列表中。当我按下“后退”按钮时,我返回到列表,但是不幸的是,显示的值仍然相同,是否可以通过某种方式发送命令以重新加载列表中的项目?要传递完整的ViewModel作为对新ActionViewModel的引用?还是告诉父级“您列表中的此视图模型已更新”的某些属性?

我敢肯定,上面的文字有点让人困惑,所以这里有一些代码可以澄清一下(希望如此)

MainViewModel.cs

private List<ActionViewModel> _actionViewModels;
public List<ActionViewModel> ActionViewModels
{
    get { return _actionViewModels; }
    set { _actionViewModels = value; RaisePropertyChanged(() => ActionViewModels); }
}


private Cirrious.MvvmCross.ViewModels.MvxCommand<int> _navigateToAction;
public System.Windows.Input.ICommand NavigateToAction
{
    get
    {
        _navigateToAction = _navigateToAction ?? new Cirrious.MvvmCross.ViewModels.MvxCommand<int>((action) => NavigateToTheDesiredAction(action));
        return _navigateToAction;
    }
}

private void NavigateToTheDesiredAction(int action)
{
    ShowViewModel<ActionViewModel>(new { id = action });
}

// Get DTOs from server or from cache and fill the list of ActionViewModels
public async Task Load()
{
    ActionService actionService = new ActionService();

    List<ActionViewModel> actionViewModels = new List<ActionViewModel>();

    MyActions = await actionService.GetMyActions();
    foreach (ActionDTO action in MyActions)
    {
        ActionViewModel actionViewModel = new ActionViewModel();
        await actionViewModel.Load(action.id);
        actionViewModels.Add(actionViewModel);
    }

    ActionViewModels = actionViewModels;
}

ActionViewModel.cs

public int ID
{
    get { return TheAction.id; }
    set { TheAction.id = value; RaisePropertyChanged(() => ID); }
}

public string Title
{
    get { return TheAction.Title; }
    set { TheAction.Title = value; RaisePropertyChanged(() => Title); }
}

public async Task Load(int actionId)
{
    ActionDTO TheAction = await actionService.GetAction(actionId);
    this.ID = TheAction.id;
    this.Title = TheAction.Title;
}

private Cirrious.MvvmCross.ViewModels.MvxCommand _save;
public System.Windows.Input.ICommand Save
{
    get
    {
        _save = _save ?? new Cirrious.MvvmCross.ViewModels.MvxCommand(PreSaveModel);
        return _save;
    }
}

private void PreSaveModel()
{
    SaveModel();
}

private async Task SaveModel()
{
    ValidationDTO result = await actionService.SaveAction(TheAction);
}

ActionService.cs

public static List<ActionDTO> AllActions = new List<ActionDTO>();

public async Task<ActionDTO> GetAction(int actionId)
{
    ActionDTO action = AllActions.FirstOrDefault(a => a.id == actionId);
    if (action == null)
    {
        int tempActionId = await LoadAction(actionId);
        if (tempActionId > 0)
            return await GetAction(actionId);
        else
            return new ActionDTO() { Error = new ValidationDTO(false, "Failed to load the action with id " + actionId, ErrorCode.InvalidActionId) };
    }
    return action;
}

private async Task<int> LoadAction(int actionId)
{
    ActionDTO action = await webservice.GetAction(actionId);
    AllActions.Add(action);
    return action.id;
}

public async Task<ValidationDTO> SaveAction(ActionDTO action)
{
    List<ActionDTO> currentList = AllActions;
    ActionDTO removeActionFromList = currentList.FirstOrDefault(a => a.id == action.id);
    if (removeActionFromList != null)
        currentList.Remove(removeActionFromList);

    currentList.Add(action);
    AllActions = currentList;
    return await webservice.SaveAction(action);
}
斯图尔特

我可以通过3种方式想到这一点。

  1. ActionService当数据更改时可能会发出某种通知。一种简单的方法是使用MvvmCross Messenger插件。这是CollectABull服务在mvvmcross视频的N + 1天中CollectionService.cs工作的方式(有关更多信息,请在http://mvvmcross.wordpress.com中观看N = 13

    这是我通常使用的方法。它具有较低的开销,使用WeakReferences(因此不会泄漏内存),易于扩展(任何对象都可以侦听更改),并且鼓励ViewModel和Model对象的松散耦合。

  2. 您可以实现某种形式的Refresh列表视图模型上的API,可以从相应的View事件(例如调用这个ViewDidAppearOnNavigatedToOnResume)。

    我通常不使用这种方法来刷新已知数据,但是我已经使用它来启用/禁用资源密集型对象-例如计时器

    对于某些形状的模型数据(尤其是更改频率),我可以想象出这种方法可能比Messenger方法更有效的情况。

  3. 您可以扩展对模型层的使用,INotifyPropertyChanged然后再扩展INotifyCollectionChanged回模型层。

    我已经做了几次,对我来说效果很好。

    如果您选择这种方法,请务必确保所有视图都使用WeakReference诸如MvvmCross绑定中使用的订阅之类的订阅来订阅更改事件,请参阅WeakSubscription如果您不这样做,那么即使UI本身删除了View,Model仍可能导致View保留在内存中。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

SwiftUI:视图模型不会更新视图

SwiftUI MVVM:子视图模型在父视图更新时重新初始化

SwiftUI-更新父视图状态时如何保留子视图状态?

Aurelia:如何将子DOM元素的视图模型绑定到父视图模型?

视图未按模型更新

无法填充视图或视图模型已更新

每次在Django中生成视图时更新模型

当模型类子属性更改时,如何生成SwiftUI视图以进行更新?

SwiftUI-刷新视图模型数组中更新的模型视图

如何基于骨干模型的响应来创建/更新骨干视图?

角度,更改模型时视图未更新

模型更新时无法让Angularjs更新视图

当模型不变时,如何更新视图?

更改模型后如何更新视图?

Java模型更新多个视图

WPF NotifyIcon不触发MouseEnter事件(显示工具提示时如何更新NotifyIcon视图模型)

更改视图模型数据时,extjs绑定的html不更新

在将数据加载到角度模型中时如何更新视图?

根据用户的视图更新来更新模型?

如何从Knockout中的另一个视图模型更新视图模型数据

如何将列表视图从视图模型绑定模型可观察集合更新到项目源

如何使用子视图模型方法制作父视图绑定命令

视图模型不更新 UI

父模型更新时未更新的子模型列表

在父视图中触发子视图模型方法:MarionetteJs

SwiftUI 视图模型更新

视图模型更新时视图未更新

如何从我的视图模型更新元素的回收器视图?

视图模型未更新