New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Templating Proposal with JSX #3252
Comments
I would rather copy jsx's semantics, while keeping things observable. We just compile to function wrappers.
…Sent from my iPhone
On May 12, 2017, at 2:56 PM, Christopher Baker ***@***.***> wrote:
TLDR
Use JSX because JSX is awesome. Also, no runtime ast parsing, so possibly more performant and smaller.
Details
JSX code is transpiled to calls to a particular function, (defaults to React.createElement, but can be switched with an @jsx pragma on a per-file or per-function basis). This does mean that any inline jsx would need to require the viewJSX function and include the pragma. Standalone files (like *.stache) would just be the jsx itself, and the require, functions, and pragma could be added by the loader. That function is called with the tagName as the first paramater, the properties as the second (an object, or null if no properties), and any children as the following arguments.
Note: within React, there are differences between JSX and HTML, mainly the use of className over class, but this is standard they adopted rather than an implicit requirement. No such limitation would exist in a jsx-based tempating system.
Events
For representing events, I would propose using onFoo syntax. <div onClick={ vm.onClick } />
Binding
One of the complications here regarding binding is that the runtime use is via function calls, and the values are grabbed, so the connection to the parent object is lost each time. This is fine for unbound values, but would interfere with binding. To solve that, I would propose an extra set of getters on CanDefine objects, which return computes or observables instead of the actual values, something like viewModel.$foo. While there would be a small performance hit here, I don't think it would be very significant.
I would propose the use of $ or _ as a prefix or suffix in order to specify binding, though I'm not crazy about it and would be open to other suggestions. <div $foo={ vm.$foo } /> <div foo$={ vm.$foo } /> <div $foo$={ vm.$foo } /> (to parent, to child, two way) <div foo={ vm.$foo } /> (two way shortcut, for when a compute is provided but no $ are present on the key)
Example
/** @jsx viewJSX */
let renderer = makeRenderer((vm) => (
<div class="foobar">
{ vm.things.map(thing => (
<div>{ thing }</div>
)) }
<div $_foo="bar" />
</div>
));
let frag = renderer({ things: [ 1, 2, 3 ] );
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or mute the thread.
|
@christopherjbaker Does your proposal differ from #3042? It appears to be the same to me. |
@matthewp I confess I had not seen that that proposal. I looked at comments on #2995 but didn't realize it was an epic and that there were other attached proposals. In structure, it is not different. I had seen hypertext before, though did not consider using it to handle can rendering. Would we be able to get performance comparable to can-stache without direct control? Or were you just proposing to using their structure (ala can-stach vs mustache)? |
@christopherjbaker You can take a look at can-hyperscript if you're interested, but it is using a lot of the same internals as can-stache (can-view-live being the big one). One of the biggest performance pieces is how it handles rendering lists. I got this to work by overwriting the One caveat, though, is that we wouldn't be able to support streaming using something like can-hyperscript. |
I think this is still a good idea. |
TLDR
Use JSX because JSX is awesome. Also, no runtime ast parsing, so possibly more performant and smaller.
Details
JSX code is transpiled to calls to a particular function, (defaults to React.createElement, but can be switched with an
@jsx
pragma on a per-file or per-function basis). This does mean that any inline jsx would need to require theviewJSX
function and include the pragma. Standalone files (like *.stache) would just be the jsx itself, and the require, functions, and pragma could be added by the loader. That function is called with the tagName as the first paramater, the properties as the second (an object, or null if no properties), and any children as the following arguments.Note: within React, there are differences between JSX and HTML, mainly the use of
className
overclass
, but this is standard they adopted rather than an implicit requirement. No such limitation would exist in a jsx-based tempating system.Events
For representing events, I would propose using onFoo syntax.
<div onClick={ vm.onClick } />
Binding
One of the complications here regarding binding is that the runtime use is via function calls, and the values are grabbed, so the connection to the parent object is lost each time. This is fine for unbound values, but would interfere with binding. To solve that, I would propose an extra set of getters on CanDefine objects, which return computes or observables instead of the actual values, something like
viewModel.$foo
. While there would be a small performance hit here, I don't think it would be very significant.I would propose the use of
$
or_
as a prefix or suffix in order to specify binding, though I'm not crazy about it and would be open to other suggestions.<div $foo={ vm.$foo } />
<div foo$={ vm.$foo } />
<div $foo$={ vm.$foo } />
(to parent, to child, two way)<div foo={ vm.$foo } />
(two way shortcut, for when a compute is provided but no $ are present on the key)Example
The text was updated successfully, but these errors were encountered: