Как дождаться обновления ObservableAsPropertyHelper в ReactiveUI

У меня есть метод, в котором я изменяю свойство, которое вызывает изменение другого свойства, поддерживающее поле которого имеет тип ObservableAsPropertyHelper. Дополнительное поле, равное ObservableAsPropertyHelper, вызывает изменение вложенного представления, поэтому для его активации требуется некоторое время. Пока не будет активировано, у меня есть пустое свойство, которое зависит от ObservableAsPropertyHelper, и мне нужно подождать, но я не знаю, как это сделать.

У меня есть образец кода.

public class MainViewModel : ReactiveObject
{
    private string _carModelName;
    private readonly ObservableAsPropertyHelper<ICarModel> _carViewModel;

    public MainViewModel()
    {
        this.LoadConfigurationCommand = ReactiveCommand.Create(this.LoadConfiguration);

        this.WhenAnyValue(x => x.CarModelName)
            .Select<string, ICarModel>(x =>
            {
                switch (x)
                {
                    case "VW":
                        return new VWModel();
                    case "BMW":
                        return new BMWViewModel();
                    default:
                        return null;
                }
            })
            .ToProperty(this, x => x.CarViewModel, out _carViewModel);

        this.CarModelName = "VW";
    }

    public string CarModelName
    {
        get => _carModelName;
        set => this.RaiseAndSetIfChanged(ref _carModelName, value);
    }

    public ICarModel CarViewModel => _carViewModel.Value;

    public ReactiveCommand<Unit, Unit> LoadConfigurationCommand { get; }        

    private LoadConfiguration()
    {
        // code which loads configuration

        this.CarModelName = configurationCarModelName; // "BMW"

        // now I want to call CarViewModel, but I have null, because modification of property is in progress
        this.CarViewModel as ICarModel;
        this.CarViewModel.Load(configurationObject);

        // how to wait for CarViewModel update to call Method with parameters?
    }
}

person Lukasz Szczygielek    schedule 16.06.2020    source источник
comment
Я бы, вероятно, добавил поле конфигурации, которое заполняется командой, и сделал бы WhenAnyValue в свойстве CarViewModel, чтобы загружать конфигурацию в автомобиль при каждом изменении автомобиля.   -  person Colt Bauman    schedule 18.06.2020
comment
@ColtBauman Я постараюсь сделать так, как вы написали. Звучит выполнимо. Возможно, это не чистый подход (поле только для хранения нового состояния), но основная цель - иметь рабочий код.   -  person Lukasz Szczygielek    schedule 18.06.2020


Ответы (1)


Итак, вы можете отреагировать на изменение и просто вызвать команду. Как только вы начнете декларативный путь, вам просто нужно объявить, что должно происходить в ответ на другие вещи. Итак, «Когда свойство моей виртуальной машины изменяется, я хочу делать эти вещи».

this.WhenAnyValue(x => x.CarModelName)
.Select<string, ICarModel>(x =>
{
    switch (x)
    {
        case "VW":
            return new VWModel();
        case "BMW":
            return new BMWViewModel();
        default:
            return null;
    }
})
.InvokeCommand(this, x => x.CarViewModel.Thing);

public interface ICarModel
{
    ReactiveCommand<Unit, Unit> Thing { get; set; }
}
person Rodney Littles    schedule 16.06.2020
comment
Я отредактировал свой вопрос. Я вызываю команду LoadConfigurationCommand, которая считывает новое значение для CarModelName и содержит данные, которые необходимо передать повторно созданному CarViewModel. Я до сих пор не понимаю, как это решить. - person Lukasz Szczygielek; 17.06.2020
comment
Я не уверен, что это так сильно меняет мой ответ. В реактивном программировании вы не ждете, ваше реактивное. Поэтому, когда значение изменится, вызовите команду. - person Rodney Littles; 17.06.2020
comment
Поэтому мне нужно изменить поток кода. Метод LoadConfiguration в настоящее время не может изменить CarModelName и вызвать метод на CarViewModel, потому что второй еще не обновлен. Возвращаясь к вашему примеру - не все изменения на CarModelName должны вызывать CarViewModel.Thing. - person Lukasz Szczygielek; 17.06.2020
comment
Так отфильтруйте их с помощью предложения Where, чтобы это происходило только в вашем конкретном случае использования? Исходя из того, что вы предоставили, это решает проблему. Мы вызываем команду в ответ на получение значения. - person Rodney Littles; 17.06.2020
comment
Я не умею фильтровать. Я могу создать метод, который будет возвращать конфигурацию, но как затем изменить CarModelName, а затем дождаться изменения CarViewModel, чтобы применить вторую часть конфигурации. Я не нашел подобного примера кода ни в документации, ни в образцах. Как вызвать метод, который возвращает результаты, а затем заполняет свойства покоя хороших моментов? - person Lukasz Szczygielek; 17.06.2020