Giter Site home page Giter Site logo

FAQ about mercury HOT 19 OPEN

raynos avatar raynos commented on June 17, 2024
FAQ

from mercury.

Comments (19)

sladiri avatar sladiri commented on June 17, 2024 1

Hi, I have tried hot-reloading with browserify, webpack and now amok. http://amokjs.com/

It looks like I am not limited to swapping the render function using amok, for example, I can change the incrementCounter function without losing state. I am fairly new to this however.

The counter example could be modified like this to force a render when the patch event from amok server happens:

var window = require('global/window');
...
function App() {
        var appState = hg.state({
            amokState: hg.value(Math.random()),
            value: hg.value(0),
            channels: {
                clicks: incrementCounter
            }
        });

        // Modify state on patch event to trigger render.
        window.addEventListener('patch', function() {
            appState.amokState.set(Math.random());
        });

        return appState;
}

from mercury.

Raynos avatar Raynos commented on June 17, 2024

Questions:

  • How do I do custom event handling? A: use data-foo: function (ev) { }
  • How do I do custom rendering? A: use a widget
  • How do I do update custom properties? A: use a hook

from mercury.

ashnur avatar ashnur commented on June 17, 2024

how does the unwrapping of state objects actually work?

from mercury.

Raynos avatar Raynos commented on June 17, 2024

The first of the FAQ is making great progress.

I'll keep this issue open so anyone else can chime in with questions here!

from mercury.

Raynos avatar Raynos commented on June 17, 2024

Questions:

  • How do you do stuff out of scope for dom props like focus()
  • How do you do stuff not well fit for data based things, like set focus once, or do something on dom element entry.

from mercury.

neonstalwart avatar neonstalwart commented on June 17, 2024

i don't know if this belongs in an FAQ but since you can't use dom-delegator for resize events (because you need to listen to resize events on window), i made my own event for it

 var hg = require('mercury'),
    resize = hg.input();

 window.addEventListener('resize', resize);

 return resize;

from mercury.

Raynos avatar Raynos commented on June 17, 2024
  • state ownership. How do you organize your state object and how do you decide who has ownership

from mercury.

Raynos avatar Raynos commented on June 17, 2024
  • arguments vs local state. Compare to react, talk about trade offs.

from mercury.

ashnur avatar ashnur commented on June 17, 2024

How to specify multiple event handlers for 'ev-*' properties?

from mercury.

neonstalwart avatar neonstalwart commented on June 17, 2024

from mercury.

fiatjaf avatar fiatjaf commented on June 17, 2024

What is the correct way to get events from Widgets?

For example, I have a CodeMirrorWidget holding a CodeMirror instance. It does a lot of things, I don't care, but I want to grab its value when it changes, but, as mercury doesn't let me handle the events normally (in fact it does, but then I don't get the observable state to update in my event callback) I don't know how to do it.

Now I'm basically doing it the crude way, passing a normal event callback function to the widget, with the global observable state embedded in it, so I can update the state, but there might be something wrong with this.

from mercury.

Raynos avatar Raynos commented on June 17, 2024

Handles created from dom-delegator are done here ( https://github.com/Raynos/dom-delegator/blob/master/dom-delegator.js#L29-L36 ).

If you have a handle and are using h you can just do

h('div', {
  'ev-click': handle
})

If you are using the DOM you can use https://github.com/Raynos/dom-delegator/blob/master/dom-delegator.js#L26

var d = mercury.Delegator();

d.addEventListener(domElem, 'click', handle)

If you want to do custom stuff with the event, i.e. transform the DOM event and pass a plain object back instead of passing on a raw DOM event you can use transformHandle ( https://github.com/Raynos/dom-delegator/blob/master/dom-delegator.js#L38-L45 )

Although I recommend you create a higher order function using BaseEvent (https://github.com/Raynos/value-event/blob/master/key.js#L1-L11)

var d = mercury.Delegator();

var MyEvent = mercury.BaseEvent(function (ev, broadcast) {
  broadcast({ value: ev.target.value })
})

d.addEventListener(domElem, 'click', MyEvent(handle))

from mercury.

Raynos avatar Raynos commented on June 17, 2024

@fiatjaf do you want to contribute a section to the FAQ documenting this in more detail.

I think your codemirror widget + dom-delegator example would be great to add somewhere :)

from mercury.

fiatjaf avatar fiatjaf commented on June 17, 2024

Ok, I postponed my work on this for a while, but now that I'm reading again and it doesn't solve my problem. CodeMirror (and many other libraries) doesn't emit DOM events, it has a custom event system and you're supposed to listen to events by calling yourCodeMirrorObject.on("change", handle).

As I could understand, however, dom-delegator only proxies DOM events, and I can't bypass dom-delegator (it gets everything in my channels and turn into dom-delegator fake handles)(also it would not be good to bypass it, as I wouldn't get the state as the first argument to my handle), so it is impossible to handle my CodeMirror events nicely.

My CodeMirrorWidget, actually: https://github.com/fiatjaf/vendasalva-app/blob/mercury/codemirror/vendasalva-widget.coffee

What I want to do:

state = function () {
  return hg.state({
    text: "foo",
    channels: {
      inputTextChanged: function (state, codemirrordata) {
        state.text.set(codemirrordata.cm.getValue())
      }
    }
  })
}

(...)

h('div', {},
  CodeMirrorWidget({
    'ev-click': state.channels.inputTextChanged
  })
})

What I'm doing, because I can't find another way:

state = function () {
  return hg.state({
    text: "foo"
  })
}

actualState = state()

standaloneHandlers = (function (state) {
  return {
    inputTextChanged: function (codemirrordata) {
      state.text.set(codemirrordata.cm.getValue())
    }
  }
})(actualState)

h('div', {},
  CodeMirrorWidget({
    'ev-click': standaloneHandlers.inputTextChanged
  })
})

What I need, in the end, is a way to let my CodeMirrorWidget fire events that dom-delegator will understand.

from mercury.

neonstalwart avatar neonstalwart commented on June 17, 2024

@fiatjaf you can generate custom DOM events yourself and tell dom-delegator to listen to those events

however, i think your point about events being tied to dom-delegator is a good one - channels cannot be fired apart from DOM interaction. due to this, i exclusively use hg.input for my events rather than hg.channels. my code is not much different to your standaloneHandlers code though so you're essentially doing the same thing. the one difference is that i put those handlers at state.events so that the render function does not need to reference standaloneHandlers via a closure. the pattern i use has update, input, component state which includes events, and render which attaches the events just like you're doing.

the code to bind state to each of the update functions can be generalized into a helper something like:

function autoWire(state, events, update) {
    Object.keys(events).forEach(function (key) {
        var respond = update[key];

        if (respond) {
            events[key](respond.bind(null, state));
        }
    });
}

// use it after generating the component state:
autoWire(state, events, update);

from mercury.

fiatjaf avatar fiatjaf commented on June 17, 2024

@neonstalwart I can see it is essentially the same hacky trick in your example but, wow, your code is much more elegant than mine, I'm astonished. I'll copy that right away. Later on I'll think about generating custom events, but I think I'll be satisfied with your solution in the cited example.

from mercury.

crabmusket avatar crabmusket commented on June 17, 2024

+1 to @ashnur's question: can we trigger multiple channels from an event?

from mercury.

ashnur avatar ashnur commented on June 17, 2024

@eightyeight use an array http://jsfiddle.net/ashnur/7vnqs7oz/

from mercury.

crabmusket avatar crabmusket commented on June 17, 2024

That's obvious and intuitive. Thanks! I'll make a PR to add it to the FAQ.

from mercury.

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.