rivets icon indicating copy to clipboard operation
rivets copied to clipboard

Nested if unbind needs to remove element

Open anshul-kai opened this issue 8 years ago • 9 comments

I realize that a newer 0.9.0 version is out. Unfortunately, I am unable to use it as its causing several issues in my application. I have created a simple JSFiddle using version 0.8.1 demonstrating this particular problem.

https://jsfiddle.net/zhqghmo4/

The proposed solution is to modify rivets.binders.if.unbind function as below:

    unbind: function() {
      if (this.nested) {
        this.nested.unbind();
        if(this.el.parentNode){
          this.el.parentNode.removeChild(this.el);    
        }
        return this.bound = false;
      }
    }

anshul-kai avatar May 27 '16 06:05 anshul-kai

@tanshul22 Are the issues caused by 0.9.0 fixed by 0.9.1 and the improved docs now?

benadamstyles avatar Aug 08 '16 15:08 benadamstyles

@Leeds-eBooks I just noticed that I have to rewrite all my function calls to make my application compliant with v9. That would be hours of work so I've deferred that effort.

I did update my JsFiddle with v0.9.1 but am having no luck. You can check it out here. Would love to hear your thoughts on this bug.

Another small improvement I made to the fix above is to check for the bound flag.

   unbind: function() {
      if (this.nested) {
        this.nested.unbind();
        if(this.bound && this.el.parentNode){
          this.el.parentNode.removeChild(this.el);    
        }
        return this.bound = false;
      }
    }

anshul-kai avatar Aug 09 '16 01:08 anshul-kai

Ok I'll take a look at the fiddle asap. Do you know about the executeFunctions configuration flag? It makes rivets retain backwards compatibility so that you don't have to rewrite all your function calls https://github.com/mikeric/rivets/blob/master/CHANGELOG.md

benadamstyles avatar Aug 09 '16 07:08 benadamstyles

No, I did not know about the executeFunctions flag. Thanks for sharing man! I verified that the bug is still present in my project after adding the executeFunctions flag on top of v0.9.1 but good to know that I don't have to re-write all my function calls :)

I realize my fix may not be ideal as I do not have my head wrapped around the entire library. Very curious to see how you propose to fix the bug.

Thanks again!

anshul-kai avatar Aug 09 '16 17:08 anshul-kai

@Leeds-eBooks I finally upgraded to 0.9.4 and everything seems to be working fine except the original issue. I know I owe you guys an example which seems a little hard to re-create in a very simple setup. The fix suggested by me on Aug 8th seems to fix the problem. I'll try to get a working example for you guys; just wanted to keep you all posted.

Thanks for all the hard work. Loving components 👍

anshul-kai avatar Oct 19 '16 22:10 anshul-kai

I'll take another look at this. Which fix was suggested to you on Aug 8th?

benadamstyles avatar Oct 20 '16 08:10 benadamstyles

To be accurate, my fix is more of a hack. It is to update rivets.binders['if']['unbind'] to as below. And I was able to create a working example :)

Notice what happens when you remove my customization to rivets.binders['if']['unbind'].

https://jsfiddle.net/gwzqhp7v/

    unbind: function() {
      if (this.nested) {
        this.nested.unbind();
        if(this.bound && this.el.parentNode){
          this.el.parentNode.removeChild(this.el);    
        }
        return this.bound = false;
      }
    }

Would be great if 0.9.5 could address this bug as well.

anshul-kai avatar Oct 20 '16 16:10 anshul-kai

@Leeds-eBooks @a-koka for bug hunt, notice that the overwritten unbind is not needed when in given fiddle you comment out this line: application.view.name = undefined; It may be something about sightglass.

Namek avatar Oct 21 '16 09:10 Namek

Here are my findings:

When name is set to 'B', the "eq 'B'" binding is made visible (attached to parentNode) and this.bound is true

When name is set to undefined, the root if binding routine calls unbind for its nested view which calls unbind for "eq 'B'" binding setting this.bound to false but "eq 'B'" element is still visible (i.e. attached to parentNode)

When name is set to 'C', the root if binding routine calls bind for its nested view which calls bind for "eq 'B'" binding but this.bound is still false making the check for this.bound being different then value evaluate to false thus not executing the routine that would detach the element

The proposed solution will work since will eliminate the discrepancy between this.bound and element visible/attached state created when root if is hidden.

But i ended with a solution to use separate flags for bind and visible/attached states making easier to reason about. Here's how i did so you can adapt if deems appropriate https://github.com/blikblum/rivets/commit/a327a8b6668bc7ff1dbbb8848f418d7e4acdbe80 Later i renamed visible to attached: https://github.com/blikblum/rivets/commit/19cba1c35ced669146f30bf10d003a988f984ab2

blikblum avatar Oct 22 '16 01:10 blikblum