2016-12-15 40 views
1

我想設置一個特定的錯誤消息,如果cetain條件輸入文本不符合。反應式用戶界面共享可觀察邏輯

基本上,如果輸入的網址是空的,我想設置ErrorHint爲「服務器URL不能爲空」

如果輸入的URL不以https ErrorHint開始應該是「服務器URL必須以https開頭的」

否則,ErrorHint應該是一個空字符串。

下面的代碼工作,但我覺得我在我的observables複製邏輯。有沒有更乾淨的方法來做到這一點?

 // invalid if the server url is empty 
     var serverUrlEmptyObservable = 
      this.WhenAnyValue(x => x.NewServerUrl) 
       .Where(string.IsNullOrWhiteSpace); 

     // invalid if the url is not empty but does not start with https 
     var serverUrlInvalidPrefixObservable = 
      this.WhenAnyValue(x => x.NewServerUrl) 
       .Where(x => !string.IsNullOrWhiteSpace(x)) 
       .Where(x => !x.StartsWith(NewServerUrlRequiredPrefix)); 

     // valid if the server url is not empty and starts with proper prefix 
     var validServerUrlObservable = 
      this.WhenAnyValue(x => x.NewServerUrl) 
       .Where(x => !string.IsNullOrWhiteSpace(x)) 
       .Where(x => x.StartsWith(NewServerUrlRequiredPrefix)); 

     // set error message based on which observable fires 
     ErrorHint = Observable.Merge(
      validServerUrlObservable.Select(x => ""), 
      serverUrlInvalidPrefixObservable.Select(x => $"Server URL must start with {NewServerUrlRequiredPrefix}"), 
      serverUrlEmptyObservable.Select(x => "Server URL cannot be empty")); 

回答

1

創建一個IObservable並使用ToProperty方法設置ErrorHint輸出屬性的值。這基本上是如何實現這個「ReactiveUI」的方式:

public class ReactiveViewModel : ReactiveObject 
{ 
    private const string NewServerUrlRequiredPrefix = "https"; 

    public ReactiveViewModel() 
    { 
     this.WhenAnyValue(x => x.NewServerUrl) 
      .Select(_ => 
      { 
       if (string.IsNullOrEmpty(NewServerUrl)) 
        return "Server URL cannot be empty"; 
       else if (!NewServerUrl.StartsWith(NewServerUrlRequiredPrefix)) 
        return $"Server URL must start with {NewServerUrlRequiredPrefix}"; 

       return string.Empty; 
      }).ToProperty(this, x => x.ErrorHint, out _errorHint); 
    } 

    private string _newServerUrl; 
    public string NewServerUrl 
    { 
     get { return _newServerUrl; } 
     set { this.RaiseAndSetIfChanged(ref _newServerUrl, value); } 
    } 

    private readonly ObservableAsPropertyHelper<string> _errorHint; 
    public string ErrorHint { get { return _errorHint.Value; } } 
} 
0

您可以通過將它的單個Select函數內部結合所有的邏輯:

ErrorHint = this.WhenAnyValue(x => x.NewServerUrl) 
    .Select(url => 
    { 
     if(string.IsNullOrWhiteSpace(url)) 
     { 
      return "Server URL cannot be empty"; 
     } 
     if(!url.StartsWith(NewServerUrlRequiredPrefix)) 
     { 
      return $"Server URL must start with {NewServerUrlRequiredPrefix}"; 
     } 
     return ""; 
    }) 
    .DistinctUntilChanged(); 

這簡直是每個NewServerUrl值映射到一個適當的錯誤消息,然後僅通知觀察者時的錯誤消息更改(使用DistinctUntilChanged)。