可以将对象传递给组件

我不知道从架构的角度来看是否可以将主题传递到组件中。我真正想要的是使组件公开可观察到的东西。但是,我想控制此可观察到的流的来源,因此这就是为什么Im询问是否可以通过该组件可以引发“事件”的主题。 好的,让我们详细说明一下。 说,我们正在设计一个组件,该组件需要用户输入,限制击键并显示结果列表。实际搜索是在另一个服务组件上进行的。 我想像这样设计SearchWidget创建函数:
//notice how I just avoided the word \"constructor\". However, conside this code as
//language agnostic. Could be RxJs or Rx .NET. It\'s Rx(ish)!

function SearchWidget(userInputStream, resultStream){
    // do some funky Rx hotness! 

}
更高级别的组件(例如控制器/介体)实际上将连接流。 显然,resultStream需要inputStream来完成工作。 在上面的示例中,从SearchWidget的角度来看,resultStream可以简单地观察到,并可以在其上侦听结果列表。但是,它将在更高级别的组件中作为“主题”实现。 相比之下,从SearchWidget的角度来看,userInputStream将是一个主题,但是它将在更高的组件级别上被实例化,因为我们需要预先获取它才能使resultStream挂接起来。但是,从更高级别的组件的角度来看,它是一个简单的观察对象。 高阶代码可能看起来像这样:
//This code lives in a higher order component (say a controller/mediator)
var resultStream = new Rx.Subject();
var userInputStream = new Rx.Subject();
userInputStream
    .Throttle(500)
    .DistinctUntilChanged()
    .Select(service.search)  //service comes from somewhere.
    .Switch()
    .Subscribe(resultStream.OnNext,
               resultStream.OnError,
               resultStream.OnCompleted);


var searchWidget = new SearchWidget(userInputStream, resultStream.AsObservable());
在上面的实现中,在初始化SearchWidget之前,我使用了userInputStream。当然我也可以这样实现:
//implementation of the search widget
function SearchWidget(resultStream){        
    var userInputStream = new Rx.Subject();
    // provide something like getUserInputStream() 
    // that will return unserInputStream.AsObservable()

    // do some funky Rx hotness! 
}

//This code lives in a higher order component (say a controller/mediator)
var resultStream = new Rx.Subject();
var searchWidget = new SearchWidget(resultStream);

//we need to initialize the searchWidget in advance to get the userInputStream

searchWidget
    .getUserInputStream() 
    .Throttle(500)
    .DistinctUntilChanged()
    .Select(service.search)  //service comes from somewhere.
    .Switch()
    .Subscribe(resultStream.OnNext,
               resultStream.OnError,
               resultStream.OnCompleted);
因此,从封装的角度来看,第二种实现可能看起来更健壮。但是,传递主题可以提供更大的灵活性。 由于使用事件流的概念非常现代,因此我在设计具有事件流的应用程序时努力寻找更大的最佳实践。     
已邀请:
  由于使用事件流的概念非常现代,因此我在设计具有事件流的应用程序时努力寻找更大的最佳实践。 当然,走在边界上很酷,但是这也意味着您必须沿着前进的道路发现“正确的道路”! 因此,请记住ISubject既是IObserver(发布部分),也是IObservable(订阅部分)-如果您的意图是您方法的客户端应为Subscriber,则仅为其提供IObservable部分(即,将主题转换为IObservable),如果您方法的客户端应该是Publisher,请将它们提供给IObserver部分。 当您使用Observable.CreateWithDisposable()时,您会看到相同的东西,其中得到的是IObserver位(因为您正在创建IObservable,因此您的工作就是发布东西!)     
对我来说,似乎只需要进行一些改组和一点思考就可以最清楚地表达正在发生的事情(Rx可能很容易被过度使用)。 在您的示例中,我发现将用户输入显示为IObservable(通过GetUserInputStream)并没有错,并且在继续处理更高级别的控制器/介体中的流时也没有错,但是对我而言,不需要传递resultStream主题。看不到任何无法在SearchWidget上使用常规方法来处理结果的原因。就像是:
var searchWidget = new SearchWidget();

searchWidget
    .GetUserInputStream() 
    .Throttle(500)
    .DistinctUntilChanged()
    .Select(service.search)  //service comes from somewhere.
    .Switch()
    .Subscribe(result => searchWidget.HandleSearchResult(result),
               ex => searchWidget.HandleSeachError(ex),
               () => searchWidget.HandleSearchComplete());
它更加明确,您将能够通过名称明确的方法以一种更加清晰的方式表示SearchWidget上的结果。 如果确实要通过Rx处理这些响应的内部,那么在内部实例化主体并处理方法调用的响应就没有错。如:
public class SearchWidget
{
   private ISubject subject;

   public SearchWidget()
   {
      this.subject = new Subject();

      //do funky rx stuff on the subject here
   }

   public void HandleSearchResult(SearchResult result)
   { 
      subject.OnNext(result);
   }

   public void HandleSearchError(Exception ex)
   {
      subject.OnError(ex);
   } 

   public void HandleSearchComplete()
   {
      subject.OnCompleted();
   }

   public IObservable<MouseEvent> GetUserInputStream()
   {
      return someUserInputStream; // whatever your stream is
   }

}
    

要回复问题请先登录注册