ipyvue
ipyvue copied to clipboard
Emitted events are blocked in VueTemplate class composition
Thanks for the great project. I was following the notebook here for creating Vue components using the new syntax vue.VueTemplate.class_component_serialization
. But no event can be pass from sub-component
to main-component
This example works, and the parent can received the event my-event
from child component
import ipyvue as vue
import traitlets
class Parent(vue.VueTemplate):
someProp = traitlets.Unicode('hello').tag(sync=True)
components = traitlets.Dict({'Child': '''
<template>
<div>
Prop from parent:
<h3> {{ childProp}} </h3>
<button @click="$emit('my-event', 'new value')">change</button>
</div>
</template>
<script>
module.exports = {
props: ['childProp'],
}
</script>
'''}).tag(sync=True)
template = traitlets.Unicode('''
<template>
<div>
<div>parent</div>
<Child :child-prop="someProp" @my-event='test'></Child>
<h3>Parent: {{ someProp }} </h3>
</div>
</template>
''').tag(sync=True)
def vue_test(self, data):
print('received from child')
self.someProp = 'changed'
parent = Parent()
parent
If I move the child component into a VueTemplate
class, The GUI is rendered correctly, however the event my-event
is blocked. No event can be pass from Child
to Parent
The parent did not receive the event.
class Child(vue.VueTemplate):
childProp = traitlets.Unicode('childProp').tag(sync=True)
template = traitlets.Unicode('''
<template>
<div>
Prop from parent:
<h3> {{ childProp }} </h3>
<button @click="$emit('my-event', 'new value')">change</button>
</div>
</template>
''').tag(sync=True)
class Parent2(vue.VueTemplate):
someProp = traitlets.Unicode('hello').tag(sync=True)
template = traitlets.Unicode('''
<template>
<div>
<Child :child-prop="someProp" @my-event="test"></Child>
<h3>Parent: {{ someProp }} </h3>
</div>
</template>
''').tag(sync=True)
components = traitlets.Dict({
'Child': Child
}).tag(sync=True, **vue.VueTemplate.class_component_serialization)
def vue_test(self, data):
print('can not receive from child')
self.someProp = 'not changed'
parent = Parent2()
parent
Is this due to the different implementation on event handling between the VueModel
and VueTemplate
?
Hi, I'd like to know if someone investigated this issue.
As I define pythonic callback, I need to use the second above example.
To get around this problem, I need to define a parent
attribute for child class.
import ipyvue as vue
import ipywidgets
import traitlets
class Child(vue.VueTemplate):
childProp = traitlets.Unicode('childProp').tag(sync=True)
template = traitlets.Unicode('''
<template>
<div>
Prop from parent:
<h3> {{ childProp }} </h3>
<button @click="at_click('new value')">change</button>
</div>
</template>
''').tag(sync=True)
def __init__(self, parent=None, *args, **kwargs):
vue.VueTemplate.__init__(self, *args, **kwargs)
self.parent = parent
def vue_at_click(self, value):
"""Callback called when clicking on the button"""
if parent is not None:
self.parent.test()
class Parent2(vue.VueTemplate):
someProp = traitlets.Unicode('hello').tag(sync=True)
child = traitlets.Any().tag(
sync=True, **ipywidgets.widget_serialization
)
template = traitlets.Unicode('''
<template>
<div>
<jupyter-widget :widget="child" />
<h3>Parent: {{ someProp }} </h3>
</div>
</template>
''').tag(sync=True)
def __init__(self, parent=None, *args, **kwargs):
vue.VueTemplate.__init__(self, *args, **kwargs)
self.child = Child(parent=self, childProp="hack")
def test(self, data):
print('can not receive from child')
self.someProp = 'not changed'
parent = Parent2()
parent
PS: I instead usually use ipyvuetify