连接两个节点

EasyReact 的重点就是让节点之间的数据流动起来,所以连接节点是很重要的。

如何连接两个节点

两个节点是通过变换来连接的,在源码目录 EasyReact/Classes/Core/NodeTransforms 中我们默认实现了了很多的变换,你也可以通过继承 EZRTransform 类来实现自己的变换,一旦我们创建好一个变换后,就可以通过如下方式进行连接了:

  1. EZRMutableNode<NSNumber *> *nodeA = [EZRMutableNode value:@1];
  2. EZRNode<NSNumber *> *nodeB = [EZRNode new];
  3. EZRTransform *transform = [EZRTransform new];
  4. transform.from = nodeA;
  5. transform.to = nodeB;
  6. NSLog(@"%@", nodeB.value); // <- @1

也可以通过 EZRNode 的 linkTo: 或者 linkTo:transform 来实现连接:

  1. EZRMutableNode<NSNumber *> *nodeA = [EZRMutableNode value:@1];
  2. EZRNode<NSNumber *> *nodeB = [EZRNode new];
  3. EZRTransform *transform = [EZRTransform new];
  4. [nodeB linkTo:nodeA transform:transform]; // <- 相当于 transform.from = nodeA; transform.to = nodeB; 请注意方向
  5. EZRMutableNode<NSNumber *> *nodeC = [EZRMutableNode value:@2];
  6. EZRNode<NSNumber *> *nodeD = [EZRNode new];
  7. [nodeD linkTo:nodeC]; // <- 相当于 [nodeD linkTo:nodeC transform:[EZRTransform new]];

断开两个节点

当两个节点不再相关的时候,你需要断开两个节点,如果你还有变换的实例,可以修改 from 或者 to 的属性来断开这两个节点或者改变连接:

  1. EZRMutableNode<NSNumber *> *nodeA = [EZRMutableNode value:@1];
  2. EZRNode<NSNumber *> *nodeB = [EZRNode new];
  3. EZRTransform *transform = [EZRTransform new];
  4. [nodeB linkTo:nodeA transform:transform];
  5. NSLog(@"%@", nodeB.value); // <- @1
  6. nodeA.value = @2;
  7. NSLog(@"%@", nodeB.value); // <- @2
  8. transform.to = nil;
  9. nodeA.value = @3;
  10. NSLog(@"%@", nodeB.value); // <- @2,不再跟随 nodeA 的变化而变化了

没有变换的实例也没有关系,EZRNode 有removeDownstreamNode:removeUpstreamNode:removeDownstreamNodesremoveUpstreamNodes等多种方法来断开与其他节点的连接:

  1. EZRMutableNode<NSNumber *> *nodeA = [EZRMutableNode value:@1];
  2. EZRNode<NSNumber *> *nodeB = [EZRNode new];
  3. [nodeB linkTo:nodeA];
  4. [nodeB removeUpstreamNode:nodeA]; // <- 断开与上游 nodeA 的全部连接
  5. [nodeA removeDownstreamNode:nodeB]; // <- 断开与下游 nodeB 的全部连接
  6. [nodeB removeUpstreamNodes]; // <- 断开所有的上游连接
  7. [nodeA removeDownstreamNodes]; // <- 断开所有的下游连接

隐式的连接两个节点

很多时候先创建节点再创建变换最后连接下游是我们默认的行为,为了更好的编码,我们提供了衍生变换的方式:

  1. EZRMutableNode<NSNumber *> *nodeA = [EZRMutableNode value:@1];
  2. EZRNode<NSNumber *> *nodeB = [nodeA fork];

它等价于:

  1. EZRMutableNode<NSNumber *> *nodeA = [EZRMutableNode value:@1];
  2. EZRNode<NSNumber *> *nodeB = [EZRNode new];
  3. [nodeB linkTo:nodeA transform:[EZRTransform new]];

相应的,其他变换也都提供了衍生变换的方式:

  1. EZRMutableNode<NSNumber *> *nodeA = [EZRMutableNode value:@1];
  2. EZRNode<NSNumber *> *nodeB = [nodeA map:^NSNumber *(NSNumber *next){
  3. return @(next.integerValue * 2);
  4. }];

它对应等同于:

  1. EZRMutableNode<NSNumber *> *nodeA = [EZRMutableNode value:@1];
  2. EZRNode<NSNumber *> *nodeB = [EZRNode new];
  3. EZRMapTransform *mapTransform = [[EZRMapTransform alloc] initWithMapBlock:^NSNumber *(NSNumber *next){
  4. return @(next.integerValue * 2);
  5. }];
  6. [nodeB linkTo:nodeA transform:mapTransform];

这种方式更直观和简单,所以下面在介绍变换的时候,会统一使用衍生的形式来介绍。