2016-04-26 25 views
0

This component from react-sticky is one of two in the library.是否有一条清晰的路径可以实现在ScalaJS + React中广泛使用上下文的React组件?

  • container,初始化和向下传递一个contextchild ...
  • sticky,其使用context和滚动位置以实现粘头的效果。

我只花了大约两个小时以上的移植这scalajs费力地进入ReactJS,我已经粘贴下面是我迄今完成的。它不编译;仍然有松动的电线。

我开始认为我应该放弃,因为也许我的道路不是很好。我试图做的是消除使用context这是sjs库中不可用与ParentProps并将其状态传递给孩子和后面。

但是,考虑到所涉及的移动部件的数量,我对此失去了信心,甚至可能会发挥作用。我需要知道是否有更好的方法或不需要移植。

package shindig.frontend.component.layout 

import fr.iscpif.scaladget.mapping.ace.PlaceHolder 
import japgolly.scalajs.react._ 
import japgolly.scalajs.react.vdom._ 
import japgolly.scalajs.react.vdom.prefix_<^._ 
import org.scalajs.dom.html.Div 
import org.scalajs.dom.window 
import org.scalajs.dom.raw.ClientRect 

import scalacss.Defaults._ 

object StickyComponent { 


    case class Props(
        isActive: Boolean     = true, 
        className: String     = "", 
        style: Seq[StyleA]     = Seq(), 
        stickyClassName: String    = "", 
        stickyStyle: Seq[StyleA]   = Seq(), 
        offsetTop: Double     = 0, 
        offsetBottom: Double     = 0, 
        stickyStateChange:() ⇒ Callback =() ⇒(), 
        contextProps: StickyContainer.Props = StickyContainer.Props() 
       ) 

    case class State(isSticky: Boolean = false, origin: PlaceHolder) 

    class Backend($:   BackendScope[Props, State]) { 

    def componentDidMount(): Unit = { 

    } 

    def getNode: TopNode = ReactDOM.findDOMNode($) 
    def getRect   = getNode.getBoundingClientRect() 
    def getY    = window.pageYOffset 

    def getOrigin(y: Double): Double = getPlaceholderRef.top + y 
    def getPlaceholderRef = $.refs.apply[Div]("placeholder").get.getDOMNode().getBoundingClientRect() 
    def getProps: Props = $.props.runNow() 

    def isBelow(y: Double, contextProps: StickyContainer.Props): Boolean = 
     y + contextProps.offset >= getOrigin(y) 

    def isAbove(y: Double, contextProps: StickyContainer.Props, offset: Double): Boolean = 
     contextProps.offset <= contextProps.bottomOfRectOrNil - offset 

    def isStickyAt(y: Double, origin: Double): Boolean = { 
     val props = getProps 
     val y = getY 
     props.isActive && isBelow(y, props.contextProps) && isAbove(y, props.contextProps, props.offsetBottom) 
    } 

    def update() = $.setState(State(

    )) 

    } 

} 

object StickyContainer { 

    case class Props(
        node: Option[TopNode] = None, 
        offset: Double = 0, 
        rect: Option[ClientRect] = None 
       ) { 
    def bottomOfRectOrNil: Double = rect match { 
     case Some(r) ⇒ r.bottom 
     case None ⇒ 0 
    } 
    } 

    case class State(
        node: Option[TopNode] = None, 
        offset: Double = 0, 
        rect: Option[_] = None 
       ) { 
    def withNode(node: TopNode) = 
     State(Some(node), offset, rect) 
    } 

    class Backend($: BackendScope[Unit, State]) { 

    def componentDidMount(): Unit = { 
     $.modState(_.withNode(ReactDOM.findDOMNode($))) 
    } 

    def render() = { 
     <.div(
     $.propsChildren() 
    ) 
    } 

    } 

    val component = 

    ReactComponentB[Unit]("StickyContainer") 
     .initialState(State()) 
     .backend[Backend]($ ⇒ new Backend($)) 
     .renderBackend 
     .build 

} 

回答

0

因此,有两个答案真的:第一个答案是,我还是不知道你怎么可能scalajs WRT reactjs内使用context,但第二个答案是,这并不重要,而且由于这我已经移植了10个小的react libs,没有问题。我专注于移植我不需要移植的方法。

您只需要按照指南在https://github.com/chandu0101/scalajs-react-components/blob/master/doc/InteropWithThirdParty.md。如果你一直在寻找一段时间,你可能已经看到了这一点,也许不相信它会起作用(我并不完全明白它会起作用),因为你所做的只是复制Props并创建一个虚假构造函数。那么,这就是你需要做的 - 很可能 - 所以在处理此任务之前,请尝试仅移植该页面上所需的内容。

相关问题