Executing a command from another command

2019-08-02 14:11发布

I have a 'hello world' form (Xamarin forms) with some fields and a submit button. There's an observable (CanSave) which controls when the SaveChangesCommand can execute. If the save button is pressed when the CanSave is false, I want to a display a message to the user.

With the code below, if I

  1. enter incorrect data
  2. click save (the error message shows)
  3. then correct the data.

CanSave becomes true and SaveChangesCommand is executed - before the button is hit again. It's as though the previously blocked button press was queued until canExecute became true.

What am I missing?

Thanks :-)

 public PersonalProfileModel()
    {
        this.SaveChangesCommand = ReactiveCommand.CreateAsyncTask(this.CanSave(),  message => this.doAllThings(message as string));
        this.ButtonClickedCommand = ReactiveCommand.Create(Observable.Return(true));
        this.ButtonClickedCommand.InvokeCommand(this.SaveChangesCommand);
        // ButtonClickedCommand.Subscribe(x => this.SaveChangesCommand.Execute("hello")); // tried this too
    }

    public ReactiveCommand<object> ButtonClickedCommand { get; set; }
    public ReactiveCommand<string> SaveChangesCommand;

    public IObservable<bool> CanSave()
    {
        var fieldsValid = this.WhenAnyValue(
            x => x.Name,
            x => x.Country,
            (f1, f2) =>
                f1 == "a"
                && f2 == "b");
        return fieldsValid;
    }

    public Task<string> doAllThings(string message)
    {
        var result = Task.Run(() =>{return "hello " + message;});
        return result;
    }

标签: reactiveui
2条回答
The star\"
2楼-- · 2019-08-02 14:34

This turned out to be a misunderstanding in the behaviour of ReactiveCommands and canExecute. See ReactiveCommand not respecting canExecute

查看更多
Emotional °昔
3楼-- · 2019-08-02 14:43

How about this:

this.SaveChangesCommand = ReactiveCommand.CreateAsyncTask(
    this.CanSave(),  
    message => this.doAllThings(message as string));

this.ButtonClickedCommand = ReactiveCommand.CreateAsyncObservable(
    SaveChangesCommand.CanExecuteObservable.StartWith(true),
    x => SaveChangesCommand.ExecuteAsync(x));

Now we're explicitly describing the relationship between the ButtonClicked's Command in terms of the SaveChangesCommand - "The ButtonClicked command is enabled when SaveChanges can be executed"

查看更多
登录 后发表回答