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 257154 - Add method for initializing technology
Summary: Add method for initializing technology
Status: RESOLVED FIXED
Alias: None
Product: platform
Classification: Unclassified
Component: Html4j (show other bugs)
Version: 8.1
Hardware: PC Mac OS X
: P4 normal (vote)
Assignee: Jaroslav Tulach
URL:
Keywords: API_REVIEW_FAST
Depends on:
Blocks:
 
Reported: 2015-12-15 15:14 UTC by maxnitribitt
Modified: 2016-02-29 18:56 UTC (History)
1 user (show)

See Also:
Issue Type: DEFECT
Exception Reporter:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description maxnitribitt 2015-12-15 15:14:47 UTC
We often need to initialize knockout before doing some extensions. Typically it is done like this:

public static void onPageLoad(){
   MyModel dummy = new MyModel();
   Models.toRaw(dummy);
   // now knockout is initialized and we can do stuff
   //  ...
}

Knockout is initialized as a side effect of this call.

There should be an explicit way of doing this, e.g. 

Models.initialize();

As one recent commenter said:

"currently it is a side-effect of some voodoo magic method."
Comment 1 Jaroslav Tulach 2015-12-15 22:13:01 UTC
I can add a test to ensure Models.toRaw continues to work, if that makes commenters happier.
Comment 2 maxnitribitt 2015-12-16 09:29:05 UTC
Example: User wants to register a custom binding. He tries to do it via 
@JSB and it fails. So I have to tell him:

"You have to create a Dummy instance of a model class and call Models.toRaw(dummy) first in order to initialize knockout". I would rather like to tell him, "call Knockout.initialize(); first".

If you look at the api doc of Models.toRaw, it "Converts an existing model into its associated, raw JSON object." But the user neither wants an instance of his Model, nor does he want the raw json object, he wants to initialize knockout.

I know, that Models.toRaw does this as a side effect, but a clueless user who realizes that he has to initialize knockout from an error message, and looks at the API has no chance to find out how to do it. And as some smart guy put it "the primary target of an API is [...] a human" ;-)
Comment 3 Jaroslav Tulach 2015-12-17 21:48:43 UTC
The thing is that in general it doesn't make much sense to initialize all Model technologies. What you want is to initialize knockout for java. So maybe you don't want new method in Models, but rather to make a call into KO4J directly.

diff -r 5b48d93e762c -r 0ced2a7be49b client/pom.xml
--- a/client/pom.xml    Thu Dec 17 22:43:36 2015 +0100
+++ b/client/pom.xml    Thu Dec 17 22:47:07 2015 +0100
@@ -151,7 +151,7 @@
         <groupId>org.netbeans.html</groupId>
         <artifactId>ko4j</artifactId>
         <version>${net.java.html.version}</version>
-        <scope>runtime</scope>
+        <scope>compile</scope>
     </dependency>
     <dependency>
       <groupId>org.testng</groupId>
diff -r 5b48d93e762c -r 0ced2a7be49b client/src/main/java/com/dukescript/demo/routing/DataModel.java
--- a/client/src/main/java/com/dukescript/demo/routing/DataModel.java   Thu Dec 17 22:43:36 2015 +0100
+++ b/client/src/main/java/com/dukescript/demo/routing/DataModel.java   Thu Dec 17 22:47:07 2015 +0100
@@ -2,8 +2,8 @@
 
 import com.dukescript.demo.routing.js.Router;
 import net.java.html.json.Model;
-import net.java.html.json.Models;
 import net.java.html.json.Property;
+import org.netbeans.html.ko4j.KO4J;
 
 @Model(className = "Data", targetId="", properties = {
     @Property (name = "page", type = String.class)
@@ -15,7 +15,7 @@
      */
     static void onPageLoad() throws Exception {
         ui = new Data("#/page1");
-        Models.toRaw(ui);
+        new KO4J().knockout().valueHasMutated(null, null);
         Router.registerBinding();
         ui.applyBindings();
     }
Comment 4 Jaroslav Tulach 2015-12-17 21:54:16 UTC
I agree that initializing KO4J by calling valueHasMutated(null, null) isn't much better than Models.toRaw. But if you (and other reviewers) want I can add:

class KO4J {
  /** Access to 'ko' object. Makes sure knockout.js is initialized, loaded
   * and its main object is accessible.
   *
   * @return JavaScript object that is usually accessible via window['ko']
   */
  public Object ko();
}
Comment 5 maxnitribitt 2015-12-18 07:09:15 UTC
Best solution would be automatic eager initialization for technologies that require it (like knockout). E.g. by loading them before onPageLoad.

This would also be the best solution, because it would support highest level of cluelessness.
Comment 6 Jaroslav Tulach 2015-12-19 20:00:10 UTC
"that require it" - however knockout doesn't require its initialization until applyBindings is used.
Comment 7 maxnitribitt 2015-12-20 15:08:07 UTC
Registering a custom binding requires knockout to be loaded.

Registering a custom binding is a very common usecase.

Registering a custom binding needs to happen before applyBindings, otherwise it's meaningless.
Comment 8 Jaroslav Tulach 2016-02-29 18:56:07 UTC
This is the maximum I can do for HTML/Java 1.3:
https://hg.netbeans.org/html4j/rev/6e836197b49e
It is still slightly magical, but at least straightforward once discovered.