xamarin.forms - 当xamarin中的应用程序启动时间形成MVVM时如何创建视图模型实例
问题描述
我的目标是访问整个应用程序的可绑定属性。但是我当前的框架 ViewModel 实例创建了多次
我的要求:我在bottomTray(CheckuoutViewModel)中有购物车数量我想在应用页面中的任何位置增加购物车数量,但是在此购物车数量在返回点击时不会更新,它仅适用于前向导航,CheckoutViewModel背后的原因每次都创建实例。这样我就可以尝试更早地进行即时创作。
这里我列出了示例 ViewModel 和调用方法
- 登录视图模型
- Checkuout ViewModel(此视图模型适用于所有页面)
- BaseNavigationViewModel(其 BaseViewModel)
截至目前,我每次都在调用 BindinContext 时,
- 新的登录视图模式(导航)
- new CheckoutViewModel(navigation) 当像 ViewModel Locator 这样的应用程序启动时间时,如何创建所有 ViewModel 实例?
我试过了
public static ViewModelLocator Locator
{
get { return locator ?? (locator = new ViewModelLocator()); }
}
和 ViewModel 定位器
public ViewModelLocator()
{
navigation = App.Current.MainPage.Navigation;
}
internal CustomTabBarViewModel CustomTabBarVM
{
get
{
return customTabBarVM ?? (customTabBarVM = new CustomTabBarViewModel(navigation));
}
}
和 CustomTabBar.xaml.cs
public CustomTabBar()
{
viewModel = App.Locator.CustomTabBarVM;
InitializeComponent();
BindingContext = viewModel;
}
和期望
App.Locator.CustomTabBarVM.BadgeCartCount = OrderObject.Instance.ORDER_OBJECT.Items.Count;
这种方法运行良好,但会产生一些导航问题
解决方案
单例实例是几乎所有 MVVM 框架(Prism、FreshMVVM 等)的共同特征。如果你没有使用框架(如果你没有,我强烈建议你考虑使用一个),下面是一个解决方案。
要获取 ViewModel 的单个实例,您可以使用App
该类来托管对象并在需要时访问它。
- 创建 ViewModel 的公共静态属性:
public static MyViewModel MyViewModelInstance { get; }
- 在应用程序的构造函数中创建一个实例
public App()
{
InitializeComponent();
MyViewModelInstance = new MyViewModel();
var myPage = new MyPage()
{
BindingContext = MyViewModelInstance
};
var navPage = new NavigationPage(myPage);
MainPage = navPage;
}
- 每当您创建新页面时,访问共享实例
// This method is just an example of how you might create a new page and wire up the view model
async void GoNextClicked(System.Object sender, System.EventArgs e)
{
var myPage = new MyPage()
{
BindingContext = App.MyViewModelInstance
};
await this.Navigation.PushAsync(myPage);
}
这种方法有一些注意事项,您是在应用程序加载时创建实例,而不是在需要时创建实例(急切加载)。因此,性能优化将Lazy<T>
用于处理这些对象的创建。然而,这是已经在 MVVM 框架中为您编写的逻辑,它们可以帮助您,您应该使用它们。
延迟加载
您可以通过延迟加载视图模型在启动时节省内存和性能,这是重写以支持此模式的示例:
public static MyViewModel MyViewModelInstance
{
get => _myViewModelInstanceFactory.Value;
}
private static Lazy<MyViewModel> _myViewModelInstanceFactory = new Lazy<MyViewModel>(() => new MyViewModel(), true);
public App()
{
InitializeComponent();
var myPage = new MyPage()
{
BindingContext = MyViewModelInstance
};
var navPage = new NavigationPage(myPage);
MainPage = navPage;
}
现在这个对象在被你的代码访问之前不会被创建,一旦它被访问,一旦它已经被创建,并且将在你的应用程序生命周期的其余部分继续存在于内存中。
推荐阅读
- sql - 查找 SQL 中的差异(棘手的情况)
- javascript - 未捕获的类型错误:在非对象上调用 CreateListFromArrayLike
- c++ - 在c ++上读取希腊字符形成文件
- android - 如何存储 Firebase 服务器时间戳加上 30 秒?
- python - 调整画布/框架大小时如何防止窗口闪烁?
- ios - 未检测到 iOS 13、Swift 5、Core NFC MiFare Classic 1K
- javascript - 打开模态窗口会从主页向下推其余元素
- gradle - 如何从字符串或类路径资源创建 RegularFileProperty?
- laravel - Laravel 中查询异常的自定义模板
- excel - 编译错误:未找到命名参数;亮点 ReadOnly:=True