> I'm no longer sure that would work. Even if I prefix my "to-go-in-data {}"
> fields in the Java class with $ so as to signal VueGwt to only put these
> properties in data {}, Vue monitors the properties defined in data {}
> *recursively. *So if I have a field which is OK to go in data {} but the
> object kept inside this field *itself *has fields which should not be
> monitored by Vue, there is no way to tell Vue not to do so... Just look at
> Vue's state.js & observer.js code...
>
Indeed the Data model is watched recursively. But this is not too much of
an issue in my opinion as long as you don't have recursion in the objects
you use in your data model. The way Vue.JS watch data model is by using
native JS getter/setter overrides, so if you don't use a property there is
not much performance cost (except setting those getter/setter).
I think the "return JSON.parse(JSON.stringify(data));" trick that you do in
> VueGwtTools.js has to go.
> For one, this call completely disconnects the original set of fields in
> data {}, from the ones that Vue will monitor. So I'm not sure that the
> current VueGwt implementation monitors the correct fields at all?
>
> Also, a copy of the data {} is anyway required in Vue.js only when you
> register a new Vue *component* (as opposed to just instantiating a new
> Vue instance):
> https://vuejs.org/v2/guide/components.html#data-Must-Be-a-Function
> Perhaps the misunderstanding and the mismatch comes from how you register
> a new component. In your example, you do it like this:
>
> @JsTypepublic class RootComponent extends VueComponent
> {
> public RootComponent()
> {
> // ChildComponent is registered to be used in our RootComponent
> this.registerComponent(new ChildComponent());
> }
> }
>
>
> In Java and also with your approach where data {}, props {} methods {} and
> all are flattened in a single Java object, it would feel much more natural
> if you do it like this:
>
> @JsTypepublic class RootComponent extends VueComponent
> {
> public RootComponent()
> {
> // ChildComponent is registered to be used in our RootComponent
> this.registerComponent(ChildComponent.class);
> }
> }
>
>
> ... and then VueGwt should map a JS *function *to the Vue "data" property
> which function should instantiate a fresh instance of the ChildComponent
> class, ending up with a separate data {} copy for each new component
> instance, as is required.
> (It is another topic how to do this reflective instantiation of the
> component with GWT anyway. Perhaps you need a Factory pattern here, in the
> absence of reflection in GWT?)
>
>
For the JSON.stringify call, as you said it disconnects the properties from
the actual instance. We could provide two choice (common data model for all
components instance, or a factory to get an instance of data model for each
component). But no matter what the data properties will get disconnected
from the component instance you create to register it.
It is because the Java "Components" are not so much components and more
templates for Vue.JS. For example their constructor is never called when a
new Component is constructed, only once when registered. So indeed the
properties you manipulate on the Java side are not the one you end up
manipulating in your JS component.
It's similar to what happens with regular Vue.JS. You usually declare your
"data" object (or function returning new instance of data) and next to it
the methods.
If in your data you have a property "hello", in your component methods you
do "this.hello", but the "this" at the moment of declaration is going to be
your component instance with it's own data when your component will be
instantiated.
So in the Java Component, the "this.hello" you do, even though in the Java
code it references the hello attribute of your Component class, at runtime
it won't be, it will just be a hello attribute on a Vue instance created by
Vue.
So I totally agree with you when you say it would feel way more natural to
pass the Class to register the component. This will be how it works if we
use Annotations (because as you said, we can't create instance on the fly
with GWT :(). Components could even be abstract, to show that they should
not be instantiated directly.
> That would be nice. I have no experience with annotation processors
> myself, unfortunately. I think Angular2-Gwt uses this approach, isn't it?
> Perhaps you can contact the Angular2-Gwt maintainer for further info on the
> subject.
>
> But then: even with that approach you have the "recursion" problem I
> mentioned at the top of my reply (Vue.js traversing all properties in data
> {} recursively), isn't it?
>
Yes it's indeed how they do it. I'll make sure to ask them some advice :).
And yes we would still get the recursivity issue. It would indeed be a
limitation compared to what you can do in Java (meaning not being able to
have recursive data structure). I don't think that would be that big of an
issue but I guess it depends on your app data model.
If you have a data model with lots of reference (like a User, reference a
UserRepository that reference everything etc...), then indeed exposing the
User in the component Data would make Vue observe the whole User repository
in each component. But you would have exactly the same issue in vanilla
Vue.JS, this is why they recommend in documentation for the objects in the
component to be simple.
Thank you again for all your remarks :), I really appreciate your feedback!
--
You received this message because you are subscribed to the Google Groups "GWT
Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/google-web-toolkit.
For more options, visit https://groups.google.com/d/optout.