-
Notifications
You must be signed in to change notification settings - Fork 27
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
@click
handler doesn't work v-on:click
works
#164
Comments
Are you aware that there are two methods for julia> @click(:me)
"v-on:click='me = true'"
julia> @click("console.log('Hi')")
"v-on:click='console.log(\\'Hi\\')'" |
It's all in the docstring... |
@hhaensel helmut I can vaguely recall seeing that first signature somewhere with symbol. I always fallback to using second one |
@hhaensel regarding the bug. I need check it again because I came across it first time when I was building a GenieBuilder app with Dani. I have not faced this in Stipple specifically. I'll create MWE and post. Thanks :) I took a note of this here because it was a few months back and I lost track of it. So didn't want to miss it again because jeremy reported this too |
just looked at the definition of |
@hhaensel A motivation for having the For examle, in a Stipple UI demo I'm preparing, I ended up using: while I think it would be desirable to be able to directly use Quasar snippets such as |
Quasar SnippetsWhen taking snippets from the internet, it's probably a good idea to make them ParsedHTMLStrings and not just Strings. Theoretically they shouldn't be parsed and the (@essenciary , we should find out why the Good newsThere is help. With the latest release of StippleUI we have released StippleUIParser, which can take snippets from the internet and turn them into julia code. It's not yet perfect but a very good starting point, I'd say. julia> doc_string = """
<template>
<div class="q-pa-md">
<q-scroll-area style="height: 230px; max-width: 300px;">
<div class="row no-wrap">
<div v-for="n in 10" :key="n" style="width: 150px" class="q-pa-sm">
Lorem @ipsum dolor sit amet consectetur adipisicing elit. Architecto fuga quae veritatis blanditiis sequi id expedita amet esse aspernatur! Iure, doloribus!
</div>
<q-btn color=\"primary\" label=\"`Animate to \${position}px`\" @click=\"scroll = true\"></q-btn>
<q-input hint=\"Please enter some words\" v-on:keyup.enter=\"process = true\" label=\"Input\" v-model=\"input\" class=\"q-my-md\"></q-input>
<q-input hint=\"Please enter a number\" label=\"Input\" v-model.number=\"numberinput\" class=\"q-my-md\"></q-input>
</div>
</q-scroll-area>
</div>
</template>
""";
julia> parse_vue_html(doc_string) |> println
template(
Stipple.Html.div(class = "q-pa-md",
scrollarea(style = "height: 230px; max-width: 300px;",
Stipple.Html.div(class = "row no-wrap", [
Stipple.Html.div(var"v-for" = "n in 10", key! = "n", style = "width: 150px", class = "q-pa-sm",
Lorem @ipsum dolor sit amet consectetur adipisicing elit. Architecto fuga quae veritatis blanditiis sequi id expedita amet esse aspernatur! Iure, doloribus!
)
btn("`Animate to \${position}px`", color = "primary", var"v-on:click" = "scroll = true")
textfield("Input", :input, hint = "Please enter some words", var"v-on:keyup.enter" = "process = true", class = "q-my-md")
numberfield("Input", :numberinput, hint = "Please enter a number", class = "q-my-md")
])
)
)
) Note: Currently the quotes around Lorem ipsum ... are not yet rendered, but that will be fixed in the next version. VS Code will tell you what's wrong 😉 |
@jeremiedb ParsedHTMLString("""<q-btn :loading="progress" color="primary" @click="progress = true">""") as part of the Alternatively, you can use the StippleUIParser, which I introduced in my previous post. Your code snippet would then be converted like this julia> parse_vue_html("""<q-btn :loading="progress" color="primary" @click="progress = true">""") |> println
btn(loading = :progress, color = "primary", var"v-on:click" = "progress = true") The result can be directly pasted in your code and modified according to your needs. Here's the validity check: julia> btn(loading = :progress, color = "primary", var"v-on:click" = "progress = true")
"<q-btn color=\"primary\" :loading=\"progress\" label v-on:click=\"progress = true\"></q-btn>" |
@jeremiedb , @AbhimanyuAryan |
@hhaensel I came across this while trying to get using GenieFramework
@genietools
@app begin
@in i = 0
@onchange i begin
@show i
end
end
function ui()
[
p("{{i}}")
btn("Change", @click("i = i+1"))
ParsedHTMLString("""<q-btn @click="i = i+1">Change @click</q-btn>""")
"""<q-btn v-on:click="i = i+1">Change v-on</q-btn>"""
]
end
@page("/", ui)
up()
|
With the latest fixes, you're almost there. Just make sure that all elements of the vector are ParsedHTMLStrings. You could just pipe the vector to ParsedHTMLString function ui()
[
p("{{i}}")
btn("Change", @click("i = i+1"))
"""<q-btn @click="i = i+1">Change @click</q-btn>"""
"""<q-btn v-on:click="i = i+1">Change v-on</q-btn>"""
] |> ParsedHTMLString
end |
So finally we got @essenciary Currently you throw an error when you find an unregistered element during parsing because you assume that you can't build it with Julia code, but you could, indeed, build it with the help of EDIT: Should I open an issue for that? |
The error is thrown by design so the users can register the component. There was a system that automatically registered components but this just hides potential errors (like a typo). |
What is wrong about using unregistered components? |
Currently you cannot use unregistered components together with sophisticated Julia code templates, because the latter is only available during parsing. |
Couldn't you offer a switch for accepting unregistered components or at least throw an error that tells you the code to register a component? |
A few things. The issue is caused by the fact that HTML elements are represented as Julia functions. If a component is not registered, it means the corresponding function does not exist. Naturally, this throws an exception. My initial solution was to capture the exception and automatically register a function. But on second thought, the issues were: 1/ throwing and catching exceptions is quite expensive in terms of performance. If we allow this, people will just use it, and the performance will be badly impacted. The switch would cause the same issues - unless we come up with an implementation that does not rely on catching Julia errors, add a warning that an unregistered component was registered (which could be missed), etc. So on this one I'd err on the side of explicitness. Sometimes making things too easy makes it easy to shoot yourself in the foot. Improving the error message with the hint on how to solve the error is a good idea. |
There is an easy and fast method to detect whether a julia function exists, just call I did this in an even more advanced way for Another approach would be to simply call |
I don't see these as being better.
Also, I don't see the issue. In JS, if you want to use a component, you register it. If you want to (also) use it in Julia, register it. Why is this problematic? Registering the component in Julia should also ideally be managed via a package, JS should be injected dynamically, etc. These are just overall better practices vs adding some random JS and introducing performance issues in Julia to make them work while avoiding one line of Julia code to register it. Maybe I'm missing something. |
Upon further consideration, with register_element a dedicated rendering method is added and is then available for all the duration of the app's execution, eliminating the error. While with xelem the error persists on every parsing, making for worse performance. |
To summarize: The (optional) auto registration of the component/HTML element is the best approach, but really a hack. It would potentially severely impact the performance of the first rendering, which will be worst felt in production, coupled with TTFx. In contrast, it can easily be fixed in development, by registering the component/element explicitly -- with a better error message that explains the solution. |
I disagre, xelem works without registering and could be used for all elements. In conrtast, I find it very strange to register the identical function with just the tag changed for each element. If you like I could come up with some demo code that is ported from parse_vue_html. |
It's not strange, because then you have code generating functions, and you can write low-code like this: div(...) do
p("Hello")
span("Today is ...")
badge(color=red)
end Without it, you'll just have xelem(div, [
xelem(p, "...")
xelem(span, "...")
xelem(badge, "...")
]) Right? |
Right, but what's bad about this? The two should have identical performance and the latter doesn't need precompilation for every element type. |
Assuming that we're still both talking about handling of unregistered components, it's about the number of operations. Say you develop your app, writing your HTML UI. The HTML is parsed 300 times in a coding session as you keep changing it and reloading. Flow per parsing: xelem: -> repeat a)-d) every time the HTML is parsed register_element: -> when html is parsed next time, skip a) -> c) and go directly to d) The xelem approach runs in O(n) (repeats every time a missing component is found) while the register_element approach runs in constant time (only happens once per component). |
Maybe I'm missing something. I would not try to use a registered function at all, so there won't be any a) or b), just call xelem for each of the elements. |
Probably we're talking about different things then... |
My details followed these topics, if I understood your questions correctly: 1/ you - why do unregistered components throw errors? 2/ you - why are there functions? 3/ you - why don't we auto-register the functions? 4/ you - why don't we use xelem instead of registering functions? 5/ you - but why register functions? |
Adding these details as well: a) Genie provides a low-code API to generate HTML - the So these are the 2 sides of the coin: |
One way to solve it without too much hassle is to add a configuration option to auto-register components but have it |
There's, hopefully, only one point that I did not understand; why can the low-code API not use |
You don't need to use
That is not the only goal. There are 2 features around this. One is allowing users to write HTML UIs with Julia via the low-code API. They directly use the low-code API to write their user interfaces. The low-code API is for them and we do care what the code looks like. For the 2nd feature, the template engine and building, yes, the auto-built code could use The arguments to not using a) the auto-generated code can be user facing - when you have a code error in the template it will error out in the built rendering function, requiring the user to open it and debug it. Looking at a page of Julia code that only has hundreds of b) no real benefit for the change. The low-code API is already available and generated at compile time and it's ready to use. What is the benefit to use |
So your offering is a switch to autoregister in case of unregistered functions, right? I'd be fine with it. The only thing that you mentioned is that registering takes time. I thought that one way of circumventing that would be to use xelem for unregistered functions. But again, I#m fine with the autoregister approach as well. |
No description provided.
The text was updated successfully, but these errors were encountered: