Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot use $if together with setting $state from within $lifecycle #44

Open
ildar-samit opened this issue Jul 2, 2015 · 9 comments
Open
Labels

Comments

@ildar-samit
Copy link

In short, I can't use $if together with setting $state from within post-load.

This works:

FamousFramework.scene('ildar:page-controller', {
    behaviors: {
        // '#home': {
        //     '$if': function(path) { return path === '/'  }
        // },
        // '#blog': {
        //     '$if': function(path) { return path === '/blog'  }
        // },
        // '#about': {
        //     '$if': function(path) { return path === '/about' }
        // },
        '.page': {
            'size': [200, 200],
            'align': [0.5, 0.5],
            'mount-point': [0.5, 0.5],
            'style': {
                'background': 'whitesmoke'
            }
        }
    },
    events: {
        '$lifecycle': {
            'post-load': function($state) {
                console.log('post-load');
                $state.set('path', '/');
            }
        },
        '.page': {
            'click': function($state) {
                console.log('WORKS');
                $state.set('path', '/blog');
            }
        }
    },
    states: {
        path: null,
    },
    tree: `
        <node id="home"  class="page">  <div> HOME  </div>  </node>
        <node id="blog"  class="page">  <div> BLOG  </div>  </node>
        <node id="about" class="page">  <div> ABOUT </div>  </node>
    `
});

This also works:

FamousFramework.scene('ildar:page-controller', {
    behaviors: {
        '#home': {
            '$if': function(path) { return path === '/'  }
        },
        '#blog': {
            '$if': function(path) { return path === '/blog'  }
        },
        '#about': {
            '$if': function(path) { return path === '/about' }
        },
        '.page': {
            'size': [200, 200],
            'align': [0.5, 0.5],
            'mount-point': [0.5, 0.5],
            'style': {
                'background': 'whitesmoke'
            }
        }
    },
    events: {
        '$lifecycle': {
            'post-load': function($state) {
                console.log('post-load');
                // 
                // If $state isn't set from here, the code works.
                // 
                // $state.set('path', '/');
            }
        },
        '.page': {
            'click': function($state) {
                console.log('WORKS');
                $state.set('path', '/blog');
            }
        }
    },
    states: {
        path: '/',
    },
    tree: `
        <node id="home"  class="page">  <div> HOME  </div>  </node>
        <node id="blog"  class="page">  <div> BLOG  </div>  </node>
        <node id="about" class="page">  <div> ABOUT </div>  </node>
    `
});

But this doesn't work:

FamousFramework.scene('ildar:page-controller', {
    behaviors: {
        '#home': {
            '$if': function(path) { return path === '/'  }
        },
        '#blog': {
            '$if': function(path) { return path === '/blog'  }
        },
        '#about': {
            '$if': function(path) { return path === '/about' }
        },
        '.page': {
            'size': [200, 200],
            'align': [0.5, 0.5],
            'mount-point': [0.5, 0.5],
            'style': {
                'background': 'whitesmoke'
            }
        }
    },
    events: {
        '$lifecycle': {
            'post-load': function($state) {
                console.log('post-load');
                $state.set('path', '/');
            }
        },
        '.page': {
            'click': function($state) {
                console.log('WORKS');
                $state.set('path', '/blog');
            }
        }
    },
    states: {
        path: null,
    },
    tree: `
        <node id="home"  class="page">  <div> HOME  </div>  </node>
        <node id="blog"  class="page">  <div> BLOG  </div>  </node>
        <node id="about" class="page">  <div> ABOUT </div>  </node>
    `
});

Could be related to #41

@djgrant
Copy link

djgrant commented Jul 3, 2015

Looks like the same issue as #47 where event handlers aren't registered to nodes that are created after the component has loaded.

In the 3rd example the click handler is not registered presumably because the .page node was created after the component loaded.

@Imti

@arkadyp
Copy link

arkadyp commented Jul 6, 2015

@ildarsamit @djgrant, thanks for bringing this issue to our attention. I'll work on getting a fix to this in ASAP.

@arkadyp
Copy link

arkadyp commented Jul 6, 2015

@ildarsamit Fixed with 6b86475.

The issue was a result of the MutationObserver being created after the post-load event was fired. In our current implementation, the MutationObserver listens to changes in the underlying detached DOM, and adds event listeners such as click whenever new <node>s are added to our scene via the control flow conduit. By fixing the order, the MutationObserver properly responds to a new node being added on the post-load event.

Can you double check that this issue has been resolved?

@djgrant
Copy link

djgrant commented Jul 7, 2015

@arkadyp how do you update an existing project? I don't see any command within the cli and famous-framework is not on npm.

@ildar-samit
Copy link
Author

@djgrant to run a project you usually run npm run dev. But that's just a script that can point anywhere, so you can actually run something like node path-to-framework/bin/famous-framework.js local-only-bootstrap --sourceFolder=components --destinationFolder=public/build --servedFolder=public --port=1618.

So here's my setup:

I git clone the Famous Framework repo (so I can switch to any branch or commit etc). Then run the bin/famous-framework.js script. My package.json file inside of my project looks like this:

{
  "name": "famous-framework-test",
  "version": "0.0.0",
  "description": "A Famous Framework component",
  "license": "",
  "private": true,
  "scripts": {
    "dev": "node ../framework/bin/famous-framework.js local-only-bootstrap --sourceFolder=components --destinationFolder=public/build --servedFolder=public --port=1618"
  }
}

This lets me run npm run dev as usual but using my version of the Framework.

I'm by no means a Node expert though, so there might be a better way, but this works for me :)

I'll try to find some time to double-check the fix, but I've already found a hackish workaround already for my own purpose.

@djgrant
Copy link

djgrant commented Jul 7, 2015

Thanks @ildarsamit. Now you've mentioned it I realise you can just reference the commit directly in package.json dependencies.

"dependencies": {
    "famous-framework": "Famous/framework#6b86475"
  }

See https://docs.npmjs.com/files/package.json#github-urls.

@ildar-samit
Copy link
Author

@djgrant oh yeah, sorry you can just do that lol. I have the repo checked out in case I wanna play around with the actual code etc.

@arkadyp arkadyp added the bug label Jul 7, 2015
@djgrant
Copy link

djgrant commented Jul 7, 2015

@arkadyp Taking a quick look at this, the original problem seems to be resolved. Thanks!

Perhaps a separate issue, it's still not possible to attach event handlers to HTML elements inserted by the inner-html behavior.

@arkadyp
Copy link

arkadyp commented Jul 7, 2015

@djgrant Thanks for taking a look.

We're aware of the separate issue of not being able to attach event handlers to HTML elements created via the inner-html behavior. Under the hood, the setContent method is called on Engine's DOMElement when the inner-html behavior is applied. Currently, there is not a good way to get a reference to the DOM element on the page via Engine's DOMElement. (See Engine Issue #183 for a discussion.) We are working with the Engine team to figure out a solution to this problem so that Framework users can apply event handlers directly to HTML elements.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants