This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

Bug 257162 - Support components in @Model annotations
Summary: Support components in @Model annotations
Status: STARTED
Alias: None
Product: platform
Classification: Unclassified
Component: Html4j (show other bugs)
Version: 8.2
Hardware: PC Linux
: P2 normal with 1 vote (vote)
Assignee: Jaroslav Tulach
URL:
Keywords: API_REVIEW_FAST
Depends on:
Blocks:
 
Reported: 2015-12-15 22:15 UTC by Jaroslav Tulach
Modified: 2015-12-26 12:09 UTC (History)
1 user (show)

See Also:
Issue Type: ENHANCEMENT
Exception Reporter:


Attachments
Sample bi-directional ko component (1.68 KB, patch)
2015-12-17 23:01 UTC, Jaroslav Tulach
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Jaroslav Tulach 2015-12-15 22:15:35 UTC
knockout supports components since version 3.2.0:
http://knockoutjs.com/documentation/component-overview.html

there is a webcomponents specification.

various other JavaScript technologies support components.

Enable support for components in HTML/Java API as well.
Comment 1 Jaroslav Tulach 2015-12-15 22:21:59 UTC
Proposal available at
http://source.apidesign.org/hg/html~html4j/rev/3534e15dc446
Comment 2 tulach 2015-12-16 08:38:48 UTC
Few observations:

jt-1) ComponentLoader.initialize(); shouldn't be called within applyBindings.
jt-2) Is "template" parameter mandatory? Is there some pre-processing of this parameter or is it upon technology how to process the value of this parameter?
jt-3) Is it possible to get list of registered/used components on application startup? Is it possible to get parameters and template by component id?
jt-4) TeaVM don't support resources :(.
Comment 3 maxnitribitt 2015-12-16 11:02:00 UTC
AE-1: Empty template - with enzo.js we had no template, but created the component via JavaScript. This is non-standard, but we could support it for convenience.

AE-2: support for template-only (http://knockoutjs.com/documentation/component-binding.html#note-template-only-components). I assume this is supported by returning void from annotated method, correct?

AE-3: Possibly in AnnotationProcessor extract text from external template file and put it in java class to support TeaVM.
Comment 4 Jaroslav Tulach 2015-12-17 23:01:16 UTC
Created attachment 157829 [details]
Sample bi-directional ko component
Comment 5 Jaroslav Tulach 2015-12-17 23:12:17 UTC
With following changes to the previous patch the component loads its values at initialization time and then only sends updates out:


+++ b/EditCompCntrl.java
@@ -3,6 +3,7 @@
 import net.java.html.json.Component;
 import net.java.html.json.ComputedProperty;
 import net.java.html.json.Model;
+import net.java.html.json.OnPropertyChange;
 import net.java.html.json.Property;
 
 @Model(className = "Params", properties = {
@@ -10,27 +11,23 @@
 })
 public final class EditCompCntrl  {
     @Model(className = "Comp", properties = {
-        @Property(name = "params", type = Params.class)
+        @Property(name = "params", type = Params.class),
+        @Property(name = "text", type = String.class)
     })
     static class CompCntrl {
         @ComputedProperty
-        static int length(Params params) {
-            String text = text(params);
+        static int length(String text) {
             return text == null ? 0 : text.length();
         }
 
-        @ComputedProperty(write = "updateText")
-        static String text(Params params) {
-            return params != null ? params.getInitialText() : null;
+        @OnPropertyChange("text")
+        static void updateText(Comp model) {
+            model.getParams().setInitialText(model.getText());
         }
-
-        static void updateText(Comp model, String ut) {
-            model.getParams().setInitialText(ut);
         }
-    }
 
     @Component(name = "message-editor", template = "EditComp.html")
     public static Comp createComponent(Params p) {
-        return new Comp(p);
+        return new Comp(p, p.getInitialText());
     }
 }
Comment 6 Jaroslav Tulach 2015-12-19 20:04:27 UTC
Re. jt-2 and AE-2 - this touches the interp between components based on different technologies. What exactly is a component? A name? But what else you need from that name? How can controls4j use the Comp component, for example? What information needs to be shared between the two technologies? It's getting complicated...
Comment 7 tulach 2015-12-21 13:28:38 UTC
I think it is not so complicated. All you need it to know what components (=component names) are available at startup. Then when component is used you need to know how to instantiate it.

The technology knows how to register new component (ko.components.register in Knockout, ngRegisterControlType in Controls.js) and also knows when component is used ("component" binding in Knockout, Type definition in Controls.js).

The registration of components can be manual (ComponentLoader.reg) or (what I prefer) automatic at startup. You can generate list of available components when annotations are processed and pass it to the technology during initialization.

When component is used the Java class with component model must be loaded, instantiated and connected with created component.

This could be problem to Knockout which needs template in time of registration. Controls.js is much more flexible because it can operate in both way - with knowledge of template during registration and without, when template is dynamically generated on component use.

BTW components should have technology attribute. You can mix different technologies in one application.
Comment 8 Jaroslav Tulach 2015-12-22 07:48:49 UTC
I'd like to mix technologies in a single DOM tree. If controls4j define component "invoice", I'd like to embed it into my ko4j app via:

<invoice params="amount: alot"></invoice>

or more verbosely as

<div data-bind="component: { name : 'invoice', params={ amount: alot } }">

The embedding should work the other way as well. Any technology should be able to embed other technology.

I understand this is more ambitious, but such sharebility would justify existence of @Component annotation in net.java.html.json package. If such sharebility cannot be achieved, then it is better if ko4j module defines its own component registration annotation and controls4j define their own. At least for now.
Comment 9 Jaroslav Tulach 2015-12-26 12:09:44 UTC
Info about angular 1 vs. 2: http://teropa.info/blog/2015/10/18/refactoring-angular-apps-to-components.html