Git Product home page Git Product logo

Comments (10)

chandu0101 avatar chandu0101 commented on July 24, 2024

nvm , solved issue , i was returning new listener every time before :( , anyway here is the working code

  trait OnClickAwaybale {
    def onClickAway
    var listener: js.Function1[Event, Unit]
  }

  class LBackend(t: BackendScope[_, _]) extends OnClickAwaybale {
    override def onClickAway: Unit = println("you killed me ")
    var listener: js.Function1[Event, Unit] = null;
  }

  val clickListener = ReactComponentB[Unit]("radioButton")
    .stateless
    .backend(new LBackend(_))
    .render((P, S, B) => {
      <.div("dude")
    })
    .configure(clickAwayMixin)
    .buildU

  def clickAwayMixin[P, S, B] = (c: ReactComponentB[P, S, B]) => {
    def initiateListener(t: ComponentScopeM[_, _, _]) = {
      val b = t.backend.asInstanceOf[OnClickAwaybale]
      b.listener =
        (e: dom.Event) => {
          val el = t.getDOMNode()
          if (el != e.target && !MDom.isDecedant(el, e.target.asInstanceOf[HTMLElement])) {
            b.onClickAway
          }
        }
    }
    c.componentDidMount(scope => {
      initiateListener(scope)
      dom.document.addEventListener("click", scope.backend.asInstanceOf[OnClickAwaybale].listener)
     })
      .componentWillUnmount(scope => dom.document.removeEventListener("click", scope.backend.asInstanceOf[OnClickAwaybale].listener))
  }

if any one know better solution please let me know :)

Thank You
Chandra

from scalajs-react.

japgolly avatar japgolly commented on July 24, 2024

I'm skimming again so if I say something stupid feel free to swear at your monitor thinking of me. I'll feel it. But yeah dude, I wouldn't do it that way. One of the biggest advantages of React is that it allows you to isolate state and have all nearly everything be simple with all dependencies being explicit and easy to reason about. You say you want different parts of the DOM to be visible but only one at a time (so click A and B is hidden, click B and A is hidden). Sounds like state to me. Anytime the UI "remembers" something, it's state. If you push your state all the way up to the very top so that you only ever have one stateful component in your SPA UI at once, you'll find you can code with zero surprises and reduce ye strain on thine brain. So maybe at the top a state saying which DOM thing is visible, then all children components recv that as a property along with callbacks to handle clicking (ie. that callback would be like saying "set me as visible now".)

from scalajs-react.

chandu0101 avatar chandu0101 commented on July 24, 2024

well i am still learner mate and i always be :) , thanks for your answer , now i learned one more new ..,

You say you want different parts of the DOM to be visible but only one at a time (so click A and B is 

hidden, click B and A is hidden).

no mate i am not trying to do this , my use case is if i have dropdown menu on page and user clicked on dropdown icon but didn't selected any option , and then if user clicks on other part of page , i want to close dropdown menu!

from scalajs-react.

japgolly avatar japgolly commented on July 24, 2024

well i am still learner mate and i always be

You and me both :)

Seems I misunderstood. The principal should still hold though. Some part of the page state should contain a value Option[A] describing the currently visible or highlighted dropdown menu item. I'm not sure how to make it clear (ie. set to None) in a nice way. Hmmm.... Dunno. Maybe ask the React JS mailing list? I like to know too. The answer might be a bit messy but I believe that's a better trade-off than invisible magic that causes problems later when you forget about it.

from scalajs-react.

chandu0101 avatar chandu0101 commented on July 24, 2024

a bit more work ... well .. hmm .. , I know FP gods will curse me , i too like FP but .. some times i let things break ;) .

from scalajs-react.

longshorej avatar longshorej commented on July 24, 2024

I'm not sure if this helps, but I've implemented this functionality in an app I'm working on by using an event system, which is pretty much the way to communicate between unrelated components in React. FB advocates using one with their Flux architecture.

I have several top level events that are configured to send out events over this system -- like document click, window location / hash change. Each event is implemented as its immutable own case class. If there's particular computation that needs to be done, its added as a method to the class. In the click example, the event contains a method that can test if the area clicked was within a supplied dom node.

A component hooks up to this event system via having its backend implement an interface to listen to events and mutate internal state locally.

Something like this:

  trait Observer {
    def observe(a: Action): Unit
  }

  object Observer {
    def apply[P, S, B <: Observer](component: ReactComponentB[P, S, B])
                                     : ReactComponentB[P, S, B] = {
      component.componentWillMount(c => RegisterSomehow(c.backend))
               .componentWillUnmount(c => UnregisterSomehow(c.backend))
    }
  }

  class Backend(bs: BackendScope[ButtonProps, Boolean]) extends Observer {
    def observe(a: Action): Unit = a match {
      case dc: DocumentClickAction =>
        if (bs.state && dc.clickWasInNode(bs.getDOMNode())) {
          bs.setState(false)
        }

      case e =>
    }
  }

val button = Observer {
    ReactComponentB[ButtonProps]("Button")
      .initialState(false)
      .backend(new Backend(_))
      .render { 
      }
}.build

Hope that helps.

from scalajs-react.

longshorej avatar longshorej commented on July 24, 2024

I suppose I'll include the last part which would be this fairly ugly forwarding of JS global events to your own homegrown event dispatcher. This would need to be executed when your app is initialized. I'm curious if anyone knows how to eliminate some of these casts, as well.

// somewhere where you initialize your app

    window.document.addEventListener("click", { (e: Event) =>
      Try(e.asInstanceOf[MouseEvent]) map { me =>
        if (me.button == 0) {
          dispatchAction(DocumentClickAction(me))
        }
      }
    }, false)

// somewhere else

case class DocumentClickAction(event: MouseEvent) extends Action {
  /**
   * Determines if the click was inside the given node.
   *
   * @param node
   * @return
   */
  def clickWasInNode(node: TopNode): Boolean = {
    @tailrec
    def isNodeInRoot(node: js.Dynamic, root: js.Dynamic): Boolean =
      if (node == root)
        true
      else if (!js.isUndefined(node.parentNode) && node.parentNode != null)
        isNodeInRoot(node.parentNode, root)
      else
        false

    isNodeInRoot(event.target.asInstanceOf[js.Dynamic], node.asInstanceOf[js.Dynamic])
  }
}

Hope it gives you some inspiration.

from scalajs-react.

chandu0101 avatar chandu0101 commented on July 24, 2024

@longshorej thanks for your points , I'll read it until i understand :) , on a side note i never used flux! ,do you have any non trivial example written in scalajs-react and flux to share ?

@japgolly mate whats your thoughts on flux architecture ? any plans for adding some built in support to our world ?

from scalajs-react.

chandu0101 avatar chandu0101 commented on July 24, 2024

i found this scalajs-react flux example https://github.com/forty/scala-js-flux-example .

from scalajs-react.

japgolly avatar japgolly commented on July 24, 2024

@longshorej Thanks for posting those examples mate. Looks very useful.

Just had an idea... it might be good to have gallery of these kind of examples for people to see different ways of doing things. The new gh-pages stuff that @chandu0101 contributed mightn't be a bad place to do it either....

@japgolly mate whats your thoughts on flux architecture ? any plans for adding some built in support to our world ?

Right now: zero thoughts. I read up on flux a few months back and was pleasantly surprised that the way I was building my own app was very similar. Then I decided I'm happy with what I've got, React is enough vendor lock-in for now.

As for me working on Flux in Scala-land, at least for now: no, I've got my hands full at the moment.

from scalajs-react.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.