These are chat archives for mithriljs/mithril.js

28th
Aug 2017
Isiah Meadows
@isiahmeadows
Aug 28 2017 06:59

@spacejack @CreaturesInUnitards @pakx Here's how you could address the interop issue with just m.render:

In components:

  1. Avoid m.redraw(), and if you must use it, expose a hook that allows consumers to provide their own replacement. Alternatively, you could manage the root internally using this:

     const Comp = {
         // Real inner view
         render(vnode) { /* ... */ },
         // View replacement - note that this *must* be a single DOM node
         view(vnode) { return m("div", this.render(vnode) },
         // `m.redraw` replacement
         redraw(vnode) { m.render(vnode.dom, this.render(vnode)) },
     }
  2. Try to keep your view as independent of component state as practically possible. For example, instead of using m("input", {value: state.value(), oninput: m.withAttr("value", state.value)}), which relies on redraws to keep the <input>'s value up to date, use m("form", onsubmit(e) { ... }) instead. (It's also slightly simpler and more responsive, since the browser knows input can't be ignored via preventDefault.)

In callers:

  1. When you use m.render, call m.render.setEventCallback with something that redraws the tree when ready.

  2. When components expose a hook for scheduling redraws, use that if you're not going to use m.render.

pakx
@pakx
Aug 28 2017 07:15
Dang, I didn't "get" either of those. Would this.render work, given this in the view lifecycle method refers to vnode.state whereas render is a method on Comp? Will need to "flems it out" (!) As for the form submit business, yeah, didn't get that either. Heck, I'm not even sure I know what interop issue is being solved :-) Will turn on brain and look at again. Laterwards!
Isiah Meadows
@isiahmeadows
Aug 28 2017 07:31

@pakx For the API thing.

  • this.redraw(vnode) operates much like m.redraw(), just localized to the node and it isn't batched.
  • this.render(vnode) basically replaces this.view(vnode), which is how you would normally render trees.
  • Yes, this.render would work as you might expect, since this === vnode.state.

For the form submit thing: it's the difference between these:

// Original
m("form", {onsubmit: ev => {
    var name = this.name()
    var address = this.address()
    // ...
}}, [
    m("input[type=text]", {
        value: this.name(),
        oninput: m.withAttr("value", this.name),
    }),
    m("input[type=text]", {
        value: this.address(),
        oninput: m.withAttr("value", this.address),
    }),
])

// New
m("form", {onsubmit: ev => {
    var form = ev.target
    var name = form.elements.name.value
    var address = form.elements.address.value
    // ...
}}, [
    m("input[type=text][name=name]"),
    m("input[type=text][name=address]"),
])
Isiah Meadows
@isiahmeadows
Aug 28 2017 08:18
Here's a gist for my API wrapper, with variants for class, closure, and object components: https://gist.github.com/isiahmeadows/76755e30dad5a4a97e6961996ef6a659
Patrik Johnson
@orbitbot
Aug 28 2017 08:46
could probably note that the form stuff is actually what you could do even when doing m.mount/route if you don't want to track the values in the component. I think most of the browsers just throw away any form content if you navigate away which might be a UX problem on larger forms, but you could ofc store the form content in the onbeforeremove lifecycle hook. Hourses for courseses
Isiah Meadows
@isiahmeadows
Aug 28 2017 09:31
@orbitbot In those cases, you could solve that by just using a shared oninput with currentTarget (which does bubble). Also, in my experience, larger forms like in surveys and tax filing programs usually save per-page, not within pages, and the few (cough online bank forms cough) that just use one big page for the whole form (which is itself really bad) don't usually save anything (which isn't much better, but my standards aren't high to begin with).
spacejack
@spacejack
Aug 28 2017 13:51
@isiahmeadows That's basically what this example did but because I was modifying the outer div's style it got ugly.
Isiah Meadows
@isiahmeadows
Aug 28 2017 13:53
Okay, and that's understandable. Note that I specifically allowed customization of the outer tag, so that should help avoid some issues.
@spacejack
Fred Daoud
@foxdonut
Aug 28 2017 13:53
All, I will be presenting Meiosis at Web Unleashed in Toronto, the conference is Sept. 25-56, if you are there let me know, it would be cool to meet :)
spacejack
@spacejack
Aug 28 2017 13:55
@foxdonut cool! I didn't know about that event.
Fred Daoud
@foxdonut
Aug 28 2017 13:56
@spacejack :thumbsup:
Also, you can add code SPEAKER to save 20%.
spacejack
@spacejack
Aug 28 2017 13:58
I'll keep that in mind :)
Scotty Simpson
@CreaturesInUnitards
Aug 28 2017 14:33
@foxdonut that’s awesome! There’s no way I can be in Toronto next month, though. Do you plan to record and share your presentation?
James Forbes
@JAForbes
Aug 28 2017 14:33

You all played with the perspective property in css transforms? So cool!

You can set a perspective, do a rotation and create a distorted trapezoid from a plain rectangle, then set perspective to 0 afterwards and rotate/translate it and it retains its shape.

Was just playing with it, super fun.

I'd seen perspective in transforms before, but I thought it was just a property that you could set once per element, not multiple times
:D
Isiah Meadows
@isiahmeadows
Aug 28 2017 14:37
3D transforms are fun to play around with - pretty awesome to make photos look almost 3D and framed like what you can do in PowerPoint.
The perspective property is very useful for setting a shared perspective point for several different items at once. Oh, and try playing with those properties with Chrome's DevTools - it's super fun.
(I've used them before myself, actually.)
James Forbes
@JAForbes
Aug 28 2017 14:59
Yeah its so good. But stuff like this: transform(...) scale(...) perspective(300px) rotateZ(30deg) perspective(0px) rotate(180deg) is just :fire:
that last rotate, has no perspective!
and the transform and scale, no perspective
literally just opting in to perspective for the rotateZ
SkyghiS
@skyghis
Aug 28 2017 15:20
Hi,
I didn't find informations on the documentation about modifying vnode.attrs.
This seem to work but I want to be sure this is safe to do it.
My simplified use case:
const Section = {
  view: vnode => [
      m(Element1, vnode.attrs),
      m(Element2, vnode.attrs)
    ]
};

const Element1 = {
  view: vnode => {
    vnode.attrs.element = "one";
    return m(Article, vnode.attrs);
  } 
};

const Element2 = {
  view: vnode => {
    vnode.attrs.element = "two";
    return m(Article, vnode.attrs);
  } 
};

const Article = {
  view: vnode => {
    // Here I use the case and section values to get content from model.
    return m("p", [vnode.attrs.case, "/", vnode.attrs.element]);
  } 
};

 m.render(document.body, m("", [
  m(Section, {case: "a"}),
  m(Section, {case: "b"})
]));
Isiah Meadows
@isiahmeadows
Aug 28 2017 15:29
@skyghis In general, consider it unsafe to modify vnode.attrs. It's undocumented because it's unsupported, and although you might find it seemingly working alright here, you may encounter nasal demons and/or other similarly bad things (such as attrs lifecycle methods getting called more often than you'd prefer when used with components).
SkyghiS
@skyghis
Aug 28 2017 15:33
ok, so I should probably use this kind of code : m(Article, {...vnode.attrs, element: "one"}) to copy the attrs
Isiah Meadows
@isiahmeadows
Aug 28 2017 15:37
I'd only pass the attributes you care about: m(Article, {case: vnode.attrs.case, element: "one"}).
(Spreading attributes avoids the potential undefined behavior, but it doesn't protect against the potential attrs lifecycle issues.)
SkyghiS
@skyghis
Aug 28 2017 15:41
I was probably biased by avoid-restrictive-interfaces
Thanks for the help
Isiah Meadows
@isiahmeadows
Aug 28 2017 15:44
Welcome. I'll note that you could censor out the offending methods (like key, oncreate, etc.), but AFAIK there isn't an existing module for it.
And also, the restrictive interfaces isn't really a problem when it's just a few components with small interfaces to begin with.
@skyghis
SkyghiS
@skyghis
Aug 28 2017 15:46
ok
Isiah Meadows
@isiahmeadows
Aug 28 2017 15:56
@skyghis You may appreciate this gist I prepared: https://gist.github.com/isiahmeadows/337857cc700a9b780522394836a47d29
SkyghiS
@skyghis
Aug 28 2017 16:17
oh great !, thanks
Isiah Meadows
@isiahmeadows
Aug 28 2017 16:21
Note: I just updated it with an edit.
Fred Daoud
@foxdonut
Aug 28 2017 16:42
@CreaturesInUnitards unfortunately, the presentation will not be recorded and that is out of my control :cry:
Pierre-Yves Gérardy
@pygy
Aug 28 2017 18:11
@spacejack for simple state management, have you seen @barneycarroll's https://github.com/barneycarroll/patchinko
Pierre-Yves Gérardy
@pygy
Aug 28 2017 18:26
@brlewis does the Ionic use Mithril?

for context: https://arstechnica.com/gadgets/2017/08/meet-fitbits-newest-device-the-fitbit-ionic-smartwatch/

All apps and watch faces are made with Javascript, CSS, and SVG.

Robin (Robert) Thomas
@RobertAKARobin
Aug 28 2017 18:30
Hi all. I'm putting Mithril on a Sinatra back-end. I'm wondering if there's a native way of Mithril's request integrating with Sinatra's stream mechanism?
http://www.sinatrarb.com/contrib/streaming.html
Patrik Johnson
@orbitbot
Aug 28 2017 18:31
mithril's request is a wrapper around xhr, so first guess would be no. However, do you know what tech is powering the Sinatra stream thingie? HTTP push, server polling (unlikely) or websockets?
Robin (Robert) Thomas
@RobertAKARobin
Aug 28 2017 18:32
I don't. I guess that would be a good first place to look!
Patrik Johnson
@orbitbot
Aug 28 2017 18:34
yeah, that should probably be enough to figure out the rest :)
patchinko doesn't immediately feel like a particularly good match for state management, at least to me. And besides, doesn't Object.assign work rtl not ltr?
spacejack
@spacejack
Aug 28 2017 18:37
@pygy thanks, that looks pretty nice! I only needed flat objects, onchange callback and the type-checking for now.
spacejack
@spacejack
Aug 28 2017 18:49
For more complex cases, I really wish IE11 supported Proxy so I could use monolite :(
Robin (Robert) Thomas
@RobertAKARobin
Aug 28 2017 19:00
For the record, you can use EventSource with Sinatra streams
Although apparently IE isn't compatible, surprise surprise
Pierre-Yves Gérardy
@pygy
Aug 28 2017 19:02
@spacejack yeah, not sure how you'd write typings for Patchinko...
Proxies are incredibly powerful, can't wait to be able to use them