流星集合重新组合重新组件

时间:2017-08-24 16:59:40

标签: reactjs meteor

为了直截了当,我想确保无论组件是否重新呈现,都会保持集合的顺序。

我有一个meteor createContainer元素,我订阅了一个集合,然后为它分配一个变量。

export default PipelineTableContainer = createContainer(() => {
  const clientsSub = Meteor.subscribe('client.findByOrganisation');
  const clients = Clients.find({}, { sort: { createdAt: -1 } ).fetch();

  return {
    clients,
  };
}, ClientsView);

ClientsView是一个行图,显示客户端何时加入。日期很重要。出于某种原因,当ClientsView组件基于状态更改重新呈现时,则会更改客户端集合的顺序,因此不再按createdAt desc对其进行排序。这会导致图表库出错,因为日期需要按顺序排列。

要重申:我想确保无论组件是否重新呈现,都会保持集合的顺序。

非常感谢任何建议,谢谢你和问候。

3 个答案:

答案 0 :(得分:1)

我也同意TAnas的回答。我认为所有的排序都应该在服务器端,而不是在客户端,你也可以在服务器端创建一个索引,试着加快速度。例如,

import akka.NotUsed
import akka.stream.{Attributes, Inlet, SinkShape}
import akka.stream.scaladsl.{Sink, Source}
import akka.stream.stage._

class OneToOneOnDemandSink[T, +M](sink: T => Sink[T, M]) extends GraphStage[SinkShape[T]] {

  val in: Inlet[T] = Inlet("OneToOneOnDemandSink.in")
  override val shape = SinkShape(in)

  override def createLogic(inheritedAttributes: Attributes) = new GraphStageLogic(shape) {

    override def preStart(): Unit = pull(in)

    val awaitingElementHandler = new InHandler {
      override def onPush(): Unit = {
        val element = grab(in)
        val innerSource = createInnerSource(element)
        val innerSink = sink(element)
        Source.fromGraph(innerSource.source).runWith(innerSink)(subFusingMaterializer)
      }

      override def onUpstreamFinish(): Unit = completeStage()

      override def onUpstreamFailure(ex: Throwable): Unit = failStage(ex)
    }
    setHandler(in, awaitingElementHandler)

    def createInnerSource(element: T): SubSourceOutlet[T] = {
      val innerSource = new SubSourceOutlet[T]("OneToOneOnDemandSink.innerSource")

      innerSource.setHandler(new OutHandler {
        override def onPull(): Unit = {
          innerSource.push(element)
          innerSource.complete()
          if (isClosed(in)) {
            completeStage()
          } else {
            pull(in)
            setHandler(in, awaitingElementHandler)
          }
        }

        override def onDownstreamFinish(): Unit = {
          innerSource.complete()
          if (isClosed(in)) {
            completeStage()
          }
        }
      })

      setHandler(in, new InHandler {
        override def onPush(): Unit = {
          val illegalStateException = new IllegalStateException("Got a push that we weren't expecting")
          innerSource.fail(illegalStateException)
          failStage(illegalStateException)
        }

        override def onUpstreamFinish(): Unit = {
          // We don't stop until the inner stream stops.
          setKeepGoing(true)
        }

        override def onUpstreamFailure(ex: Throwable): Unit = {
          innerSource.fail(ex)
          failStage(ex)
        }
      })

      innerSource
    }
  }
}

object OneToOneOnDemandSink {

  def apply[T, M](sink: T => Sink[T, M]): Sink[T, NotUsed] = Sink.fromGraph(new OneToOneOnDemandSink(sink))
}

如果你想。

答案 1 :(得分:0)

只是一个快速猜测,但如果您在发布本身中订购查询结果,这应该可以解决您的问题。如果您对其他组件使用相同的发布,则可以创建另一个名为client.findByOrganisationOrdered的发布,并在组件中调用它。

如果采用这种方法,您不需要对客户的收藏品进行排序,因为您保证已经订购了出版物的结果。

希望这会有所帮助。如果我不想查看该出版物。

答案 2 :(得分:0)

免责声明:这不能解决收集重新排序的问题,但它确实允许应用程序按预期运行:

this.state.clients.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());

此ES6函数允许我在使用之前按升序/降序对集合进行排序,因此无论集合是否在重新渲染时重新排序,这将始终触发并确保顺序正确。

如果有人知道为什么该系列重新订购仍然会受到赞赏。