#255421: A change to @Model property needs to be reported to knockout.js unless it is the same reference.
1.1 --- a/json-tck/src/main/java/net/java/html/json/tests/KnockoutTest.java Fri Sep 18 10:42:15 2015 +0200
1.2 +++ b/json-tck/src/main/java/net/java/html/json/tests/KnockoutTest.java Sat Sep 19 15:05:59 2015 +0200
1.3 @@ -305,6 +305,33 @@
1.4
1.5 Utils.exposeHTML(KnockoutTest.class, "");
1.6 }
1.7 +
1.8 + @KOTest public void nestedObjectEqualsChange() throws Exception {
1.9 + nestedObjectEqualsChange(true);
1.10 + }
1.11 +
1.12 + @KOTest public void nestedObjectChange() throws Exception {
1.13 + nestedObjectEqualsChange(false);
1.14 + }
1.15 + private void nestedObjectEqualsChange(boolean preApply) throws Exception {
1.16 + Utils.exposeHTML(KnockoutTest.class,
1.17 +" <div data-bind='with: archetype'>\n" +
1.18 +" <input id='input' data-bind='value: groupId'></input>\n" +
1.19 +" </div>\n"
1.20 + );
1.21 +
1.22 + js = Models.bind(new KnockoutModel(), newContext());
1.23 + if (preApply) {
1.24 + js.applyBindings();
1.25 + }
1.26 + js.setArchetype(new ArchetypeData());
1.27 + js.getArchetype().setGroupId("org.netbeans.html");
1.28 + js.applyBindings();
1.29 +
1.30 + String v = getSetInput("input", null);
1.31 + assertEquals("org.netbeans.html", v, "groupId has been changed");
1.32 + Utils.exposeHTML(KnockoutTest.class, "");
1.33 + }
1.34
1.35 @KOTest public void modifyValueAssertAsyncChangeInModel() throws Exception {
1.36 if (js == null) {
2.1 --- a/json/src/main/java/org/netbeans/html/json/impl/ModelProcessor.java Fri Sep 18 10:42:15 2015 +0200
2.2 +++ b/json/src/main/java/org/netbeans/html/json/impl/ModelProcessor.java Sat Sep 19 15:05:59 2015 +0200
2.3 @@ -589,10 +589,10 @@
2.4 w.write(" proto.verifyUnlocked();\n");
2.5 w.write(" Object o = prop_" + p.name() + ";\n");
2.6 if (isModel[0]) {
2.7 + w.write(" if (o == v) return;\n");
2.8 w.write(" prop_" + p.name() + " = v;\n");
2.9 + } else {
2.10 w.write(" if (TYPE.isSame(o , v)) return;\n");
2.11 - } else {
2.12 - w.write(" if (TYPE.isSame(prop_" + p.name() + ", v)) return;\n");
2.13 w.write(" prop_" + p.name() + " = v;\n");
2.14 }
2.15 w.write(" proto.valueHasMutated(\"" + p.name() + "\", o, v);\n");
3.1 --- a/json/src/test/java/org/netbeans/html/json/impl/DeepChangeTest.java Fri Sep 18 10:42:15 2015 +0200
3.2 +++ b/json/src/test/java/org/netbeans/html/json/impl/DeepChangeTest.java Sat Sep 19 15:05:59 2015 +0200
3.3 @@ -92,11 +92,19 @@
3.4 }
3.5 @ComputedProperty
3.6 static String sndName(MyY one) {
3.7 - return one.getValue().toUpperCase();
3.8 + if (one == null || one.getValue() == null) {
3.9 + return null;
3.10 + } else {
3.11 + return one.getValue().toUpperCase();
3.12 + }
3.13 }
3.14 @ComputedProperty @Transitive(deep = false)
3.15 static String noName(MyY one) {
3.16 - return one.getValue().toUpperCase();
3.17 + if (one == null || one.getValue() == null) {
3.18 + return null;
3.19 + } else {
3.20 + return one.getValue().toUpperCase();
3.21 + }
3.22 }
3.23 @ComputedProperty @Transitive(deep = true)
3.24 static String thrdName(MyY one) {
3.25 @@ -450,6 +458,28 @@
3.26 }
3.27
3.28 @Test
3.29 + public void rebindReplacesTheInstanceAndNotifies() throws Exception {
3.30 + BrwsrCtx ctx = Contexts.newBuilder().build();
3.31 + final MyY one = Models.bind(new MyY(), ctx);
3.32 + MyX p = Models.bind(
3.33 + new MyX(one, new MyY("Hi", 333), new MyY("Hello", 999)), c
3.34 + ).applyBindings();
3.35 +
3.36 + Map m = (Map) Models.toRaw(p);
3.37 +
3.38 + Object v = m.get("one");
3.39 + assertNotNull(v, "Value should be in the map");
3.40 + One o = (One) v;
3.41 + assertEquals(o.changes, 0, "No changes yet");
3.42 +
3.43 + MyY y = Models.bind(new MyY(), ctx);
3.44 + p.setOne(y);
3.45 +
3.46 + assertSame(p.getOne(), y);
3.47 + assertSame(o.changes, 1, "One change now");
3.48 + }
3.49 +
3.50 + @Test
3.51 public void mixingWithCloneIsOK() throws Exception {
3.52 BrwsrCtx ctx = Contexts.newBuilder().build();
3.53 final MyY one = Models.bind(new MyY("Ahoj", 0), ctx);