Cannot use `$if` together with setting `$state` from within `$lifecycle`
Opened this issue · 9 comments
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
@ildarsamit @djgrant, thanks for bringing this issue to our attention. I'll work on getting a fix to this in ASAP.
@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?
@arkadyp how do you update an existing project? I don't see any command within the cli and famous-framework is not on npm.
@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.
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"
}
@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 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.
@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.