У меня есть приложение Silverlight с несколькими графиками и верхним элементом управления датой, который позволяет пользователю устанавливать диапазон дат (например, 1 июля - 30 сентября).
Обычно, когда пользователь изменяет диапазон дат, выполняется команда, которая устанавливает для свойства ViewModel DateRange
новое значение. Сеттер DateRange
вызывает метод RunQueries
, который запрашивает новые данные и устанавливает свойства Data1
и Data2
с результатами этих запросов. Графики, связанные с Data1
или Data2
, обновляются соответствующим образом. Ниже приведен базовый код ViewModel; обратите внимание на вызов метода RunQueries
в установщике DateRange
.
В настоящее время в действительности уже существует более двух сборов данных, и по мере расширения приложения они продолжают добавляться. Кроме того, не все графики видны одновременно; иногда виден только один график. Но когда пользователь изменяет диапазон дат, все запросы для получения всех данных, необходимых для любого из графиков, перезапускаются с новыми датами начала и окончания. Это кажется мне очень неэффективным - возможно, нужно выполнить только один запрос!
Итак, мой вопрос - как мне реализовать отложенные запросы данных в моем классе ViewModel?
Вот две идеи, которые я рассматривал:
- Отслеживайте, какие коллекции данных являются актуальными, и затем проверяйте метод получения данных, нужно ли выполнять запрос.
- Разбейте ViewModel на несколько подклассов, по одному для каждого графика, и пусть каждая ViewModel будет управлять своими собственными данными с помощью базового класса, отслеживающего DateRange.
Обе идеи кажутся сложными для реализации, и мне было интересно - есть ли стандартный подход к этому? Я что-то упустил в шаблоне проектирования MVVM, который решает эту проблему?
Вот очень упрощенная версия моего класса ViewModel:
public class MyViewModel: INotifyPropertyChanged
{
private ObservableCollection<MyData> _Data1;
private ObservableCollection<MyData> _Data2;
private MyDateRange _DateRange;
public ObservableCollection<MyData> Data1
{
get
{
return _Data1;
}
set
{
if (_Data1 != value)
{
_Data1 = value;
NotifyPropertyChanged("Data1");
}
}
}
// getter and setter for Data2 go here
public MyDateRange DateRange
{
get
{
return _DateRange;
}
set
{
if (_DateRange != value)
{
_DateRange = value;
NotifyPropertyChanged("DateRange");
// if date range changed, need to query for stats again
RunQueries();
}
}
}
private void RunQueries()
{
GetData1();
GetData2();
}
private void GetData1()
{
// call wcf service to get the data
}
private void GetData1Completed(object s, EventArgs e)
{
// update Data1 property with results of service call
}
// etc
}