Comments (10)
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.
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.
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.
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.
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.
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.
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.
@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.
i found this scalajs-react flux example https://github.com/forty/scala-js-flux-example .
from scalajs-react.
@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)
- Export `assertOuterHTML` HOT 1
- Deprecate `Mounted` component types HOT 2
- Add default arg to `ReactTestUtils.withRendered` HOT 1
- ScalaFnComponent is anonymous HOT 2
- Consider using `DocumentFragments` in `ReactTestUtils` HOT 1
- Re-evaluate `ComponentDom` post- React 18
- Is there a way to integrate Components with cats.effect.Ref? HOT 1
- Ref not always set HOT 2
- Syntax to integrate `useContext` with context function in Scala 3 HOT 1
- Compilation fails in Scala 3 when deriving Reusability for case classes with multiple parameter groups HOT 1
- Missing getDerivedStateFromError
- Missing / misspelled packages in MODULES.md HOT 1
- Add support for Discussions tab in Github HOT 1
- Modern testing recipe?
- Cannot mix static and dynamic routes even if conditional
- A minimal setup fails with Scala 3 HOT 5
- Provide default IO/SyncIO error handler for component
- ScalaFnComponent doesn't include displayName HOT 1
- Another way to define hook components
- AsyncCallback + cats, gracefully handling errors with EitherT: unexpected behaviour HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from scalajs-react.