diff --git a/hsp/rt/cptwrapper.js b/hsp/rt/cptwrapper.js index 5549d7a..02ad23c 100644 --- a/hsp/rt/cptwrapper.js +++ b/hsp/rt/cptwrapper.js @@ -152,15 +152,17 @@ var CptWrapper = klass({ $dispose : function () { // unobserve properties and events + var c=this.cpt; + if (c && c.$dispose) { + // call $dispose before removing the observer in case + // there is a last synchronization to do + c.$dispose(); + } if (this._cptChgeCb) { json.unobserve(this.cpt, this._cptChgeCb); this._cptChgeCb = null; } - var c=this.cpt; if (c) { - if (c.$dispose) { - c.$dispose(); - } c.nodeInstance = null; this.cpt = null; } @@ -397,7 +399,7 @@ function createCptWrapper(Ctl, cptArgs) { if (attributes) { for (var k in attributes) { - + // set the template attribute value on the component instance if (attributes.hasOwnProperty(k)) { att=cw.cpt.attributes[k]; diff --git a/public/test/rt/cptintegration.spec.hsp b/public/test/rt/cptintegration.spec.hsp index 1f73ae6..00cffa7 100644 --- a/public/test/rt/cptintegration.spec.hsp +++ b/public/test/rt/cptintegration.spec.hsp @@ -62,12 +62,58 @@ var TestCtrl1=klass({ # /template +var TextareaWithOnDisposeCtrl=klass({ + attributes:{ + text: {type:"string",binding:"2-way"} + }, + $refresh: function() { + this.onTextChange(); + }, + onTextChange: function () { + var textarea = this.$getElement(0); + if (textarea) { + textarea.value = this.text; + } + }, + $dispose: function() { + var textarea = this.$getElement(0); + if (textarea) { + this.text = textarea.value; + } + } +}); + +# template textareaWithOnDispose using c:TextareaWithOnDisposeCtrl + +# /template + +# template useTextarea(data) + {if data.visible} + <#textareaWithOnDispose text="{data.text}" /> + {/if} +# /template + describe("External component integration", function () { beforeEach(function() { msg=''; refreshCount=0; }); + it("validates $dispose is called before bindings are removed", function () { + var firstValue = "hello"; + var h=ht.newTestContext(), d={visible: true, text:firstValue}; + useTextarea(d).render(h.container); + var textarea = h("textarea"); + expect(textarea.value()).to.equal(firstValue); + expect(d.text).to.equal(firstValue); + var secondValue = "new value"; + textarea.type(secondValue); + expect(textarea.value()).to.equal(secondValue); + expect(d.text).to.equal(firstValue); // still the first value because the update in the data model is on dispose + h.$set(d,"visible", false); + expect(d.text).to.equal(secondValue); // data model update normally happens when disposing the textarea on the previous line + }); + it("validates $getElement() method through direct template call", function() { var h=ht.newTestContext(), d={value:"hello"};