在ViewModel中检索REST数据

本文关键字:REST 数据 检索 ViewModel | 更新日期: 2023-09-27 18:15:27

我试图创建一个应用程序,与使用MVVM的REST api集成。我正在努力从我的视图模型中的端点提取数据并将数据绑定到我的视图。以下是我到目前为止所做的测试。

视图模型
class MainViewModel : INotifyPropertyChanged
{
    public MainViewModel()
    {
    }
    private List<Schedule> schedules;
    public List<Schedule> Schedules
    {
        get
        {
            if (schedules == null)
                GetData();
            return schedules;
        }
        set
        {
            schedules = value;
            RaisePropertyChanged("Schedules");
        }
    }
    private string homeTeam;
    public string HomeTeam
    {
        get
        {
            return homeTeam;
        }
        set
        {
            homeTeam = value;
            RaisePropertyChanged("HomeTeam");
        }
    }
    private async void GetData()
    {
        // Simulate pulling data from api
        string response;
        StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(new Uri(@"ms-appx:///DesignData/GetLive.json"));
        using (StreamReader sRead = new StreamReader(await file.OpenStreamForReadAsync()))
            response = await sRead.ReadToEndAsync();
        // Deserialize data to class
        LiveStreamModel liveGames = JsonConvert.DeserializeObject<LiveStreamModel>(response);
    }
    public event PropertyChangedEventHandler PropertyChanged;
    private void RaisePropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
视图

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <ListView ItemsSource="{Binding Schedules}">
        <ListView.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding HomeTeam}" />
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</Grid>

模型
class LiveStreamModel
{
    public string Status { get; set; }
    public string msg { get; set; }
    public List<Schedule> schedule { get; set; }
    public IEnumerator<Schedule> GetEnumerator()
    {
        return this.schedule.GetEnumerator();
    }
}
public class Schedule
{
    public int id { get; set; }
    public string @event { get; set; }
    public string homeTeam { get; set; }
    public int homeScore { get; set; }
    public string awayTeam { get; set; }
    public int awayScore { get; set; }
    public string startTime { get; set; }
    public int period { get; set; }
    public int isHd { get; set; }
    public int isPlaying { get; set; }
    public int isWMV { get; set; }
    public int isFlash { get; set; }
    public int isiStream { get; set; }
    public string feedType { get; set; }
    public string srcUrl { get; set; }
    public string hdUrl { get; set; }
    public string sdUrl { get; set; }
    public string trueLiveSD { get; set; }
    public string trueLiveHD { get; set; }
}

通常在过去,我会调用GetData()方法在我的视图的代码后面,并设置ItemSource为ListView那里。我怎样才能使它正常工作?

在ViewModel中检索REST数据

在视图模型中设置属性:

// Deserialize data to class
LiveStreamModel liveGames = JsonConvert.DeserializeObject<LiveStreamModel>(response);
Schedules = liveGames.schedule;

并确保将数据模板中的文本块数据绑定到Schedule类型的属性(那里的数据绑定针对列表项,而不是视图模型,因此视图模型的HomeTeam属性未使用):

<ListView ItemsSource="{Binding Schedules}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding homeTeam}" />
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

顺便说一句。Schedules的getter不应该像这样调用GetData并期望schedules被初始化。相反,显式设置字段,然后您可以异步调用GetData来开始加载数据(然后更新属性):

get
{
    if (schedules == null)
    {
        schedules = new List<Schedule>();
        GetData();
    }
    return schedules;
}

更好的方法是在其他地方显式地调用GetData(),这样您就可以显式地设置视图模型,而不必在(不受监视的)后台某处运行异步进程。