I create a dojo app with following render function.
...
protected render() {
let zombie = w(Zombie,{}); //zombie has a function walk();
return v('div', [
v('div',{
style: "position: relative;height:500px;"
},[
zombie
])
])
}
...
And Zombie widget has a walk function.how and where can I call it from App?
We actually can't call the child widget method, however we can call parent widget method from child widget by calling callbackFunction we passed in below code.
export default class DemoWidget extends WidgetBase {
protected callbackFunction() {
console.log("callbackFunction");
}
protected render() {
let zombie = w(Zombie,{
callbackFunction: this.callbackFunction
}); //zombie has a function walk();
return v('div',
[ v('div',{ style: "position: relative;height:500px;" },
[ zombie ]) ])
}
}
}
Related
I am looking in the setup function to render an array of buttons. For simplicity purposes I have provided this example below.
When I use an array and push or assign values as default, then place the array with in the render function I do not see any reactivity on click.
setup(props, {emit, slots}) {
const base_number = ref(1)
const base_offset= computed(()=> { return base.value + 2 })
let buttons = [base_offset.value]
let pageClick = (event , pageNumber ) => {
base_number.value = 3
}
return h("ul",{ class: "pagination", 'onClick' : event => { pageClick(event, 1)}},
buttons
)
However when I place the array of components like so in the return , reactivity and value updating works.
//On click will update base_offset
return h("ul",{ class: "pagination", 'onClick' : event => { pageClick(event, 1)}},
[base_offset.value]
)
}
What am I missing and is it possible to pass in a array of vnodes?
Instead of returning the VNode array directly from setup(), it should return a render function that returns a VNode array (and you should see a browser console warning regarding this):
export default {
setup() {
// return h(...) ❌
return () => h(...) ✅
}
}
Within that render function, create the buttons array of VNodes. Note that VNodes created outside of the render function are not reactive.
export default {
setup() {
//...
// ❌ non-reactive buttons array
// let buttons = [base_offset.value, base_offset.value + 2, base_offset.value + 4]
return () => {
// ✅ reactive buttons array
let buttons = [base_offset.value, base_offset.value + 2, base_offset.value + 4]
return h(
'ul',
{
class: 'pagination',
onClick: (event) => {
pageClick(event, 1)
},
},
buttons
)
}
}
}
demo
The function called by the subscription function triggers twice.
The publisher is not being used in an activate or attached function, but in an async function of a different class. Both classes recieve the same EventAggregator through binding.
Console.Trace() has the same routes in both cases. The Publish/Subscribe set is unique and not used by any other classes.
async sender(item:any):Promise<void> {
this.dialogService.open({
viewModel: CaModalConfirm,
model: {
color: this.color
}
}).whenClosed(async response => {
if (response.wasCancelled === false) {
this.moduleName = params.params.moduleId;
await this.selectionEventAggregator.publish('requestSelection',{item: item});
this.elementEventAggregator.publish('hideSidebar');
}
});
}
---------------------------------------------
attached() {
this.subscriptions.push(
this.selectionEventAggregator.subscribe(
'requestSelection',
params => this.sendSelection(params)
)
);
}
sendSelection(params):void {
console.trace(params);
this.selectionEventAggregator.publish(
'sendSelected',
{
selection: this.itemSelection,
item: params.item
}
);
}
The Custom Element which contained the custom Element with the Subscription has been used twice, which caused the issue. This was not an EventAggregator issue.
I'm working in VueJS. I'm trying to bind a class to one element based on an existence of a class on another element. The below is in a :for loop to print out the list.
The '#accordion-'+(index+1)) is the id of the div I want to check to see if a class exists on it.
I wrote a method and it works UNTIL I check the element's classList. Right now, I'm only doing a console log, but eventually this will return true and hopefully the class will apply.
methods: {
existingTopic: function(lcDivID) {
const element = document.querySelector(lcDivID);
console.log(element); //It gives me the element.
/* The below is where it crashes */
console.log(element.classList.contains("collapsePanelExistingTopic"));
}
}
I find it so frustrating. I've spent a day on this without any results. Any help you can provide it would be great.
Here it is, you can also use this.$el as document
...
methods: {
hasClass() {
const element = this.$el.querySelector('h1')
if (element.classList.contains('your-class-here')) {
console.log(true)
this.$el.querySelector('anotherelement').classList.add("your-another-class");
} else {
console.log(false)
}
}
},
mounted() {
this.hasClass()
}
...
Alternative
<h1 class="mb-5 fs-lg" ref="myElement">Sign up</h1>
...
methods: {
hasClass() {
const element = this.$refs.myElement
if (element.classList.contains('mb-5')) {
console.log(true)
this.$el.querySelector('anotherelement').classList.add("your-another-class");
} else {
console.log(false)
}
}
},
mounted() {
this.hasClass()
}
...
So you can define ref as :ref="index+1" in your loop
export class GraphComponent extends React.Component{
constructor(){
super();
this.state={data:[],data20:[]};
}
render(){
var Highcharts='Highcharts';
let self=this;
var conf={
chart: {
type: 'spline',
animation: Highcharts.svg,
marginRight: 10,
events: {
load: function () {
var series = this.series[0],i=0,j=1,k=0;
var p=self.state.data; // Access State variable here
}
}
}
series: [{
name: 'Random data',
data: this.state.data20 / Accessible Here
}]
}
return (<ChartView style={{height:300}} config={conf} options={options}></ChartView>);
}
}
{"data":[{"x":154745486745,"y":0.5} // some 50-60 objects like this]}
I am getting this data from JSON/SERVER into state.data20(first 20) and state.data(rest of them). state.data20 are plotted. state.data is not Accessible in the Charts event load function. I have tried few methods but still failed.
With Self reference Image
Without Self reference Image
Try saving a reference do this on a variable. Check it out:
export class GraphComponent extends React.Component{
constructor(){
super();
this.state={data:[],data20:[]};
}
render(){
var Highcharts='Highcharts';
// Declare a variable to keep a reference to react context
let self = this;
var conf={
chart: {
type: 'spline',
animation: Highcharts.svg,
marginRight: 10,
events: {
load: function () {
var series = this.series[0],i=0,j=1,k=0;
var p = self.state.data; // Access State variable using self
}
}
}
}
return (<ChartView style={{height:300}} config={conf} options={options}></ChartView>);
}
}
I have a Qt application that calls qt_update_values() to the main QML component. I want to send the new values to a specific delegate. How do I connect update_values() from the main component to be received by a specific child component, which is defined in another qml?
I have tried defining Connections in the child, but I am not sure what target I need to define...
In the main.qml i have something similar to this:
...
signal update_values(new_values)
function qt_update_values(newValues){
update_values(newValues);
}
Repeater {
id:idRepeater
model: 3
Rectangle {
id:example
Text{ text: "hello"}
...
AnotherComponent {name: "name", othervariables: "others"}
}
}
...
Then on AnotherComponent.qml i have:
...
signal update_values_child(new_values)
function onUpdate_values(newValues){
textid = newValues;
}
Text{ id:textid}
...
You don't connect from the parent to the main, but the other way around like this:
...
id: idOfTheParent // <=== THIS IS IMPORTANT
signal update_values(new_values)
function qt_update_values(newValues){
update_values(newValues);
}
Repeater {
id:idRepeater
model: 3
Rectangle {
id:example
Text{ text: "hello"}
...
AnotherComponent {
id: idOfAnotherComponent // This ID is only available in the
// scope of the Component
// that will be instantiated by the
// Repeater, i.e. children of the Rectangle
name: "name"
othervariables: "others"
}
Connections {
target: idOfTheParent
onUpdate_values: idOfAnotherComponent.dosomethingWith(new_values)
}
}
}
...
You could also use signal.connect() to add new connections
Repeater {
model: 10
delegate: Item { ... }
onItemAdded: {
idOfTheParent.update_values.connect(function() { // do what you want })
}
}
But if it is only broadcasting of a new value, the declarative way would be, to have properties in your delegate, and bind them to the properties that held the changeing values:
...
id: idOfTheParent
property var valueThatWillChange
Repeater {
model: 10
delegate: Item {
property int valueThatShallChangeToo: idOfTheParent.valueThatWillChange
}
}
...
To have all of it with different signals ofc. is possible:
For the Connections-solution the simplest thing is to call doSomething only if it is the right delegate instance:
// in the delegate
Connections {
target: idOfTheParent
onValue1Updated: if (index === 1) doYourStuff()
onValue2Updated: if (index === 2) doYourStuff()
onValue...
}
But this is easier with the second method:
id: idOfTheParent
Repeater {
model: 10
delegate: SomeItem {
function doSomething() { console.log(index, 'does something')
}
onItemAdded: {
idOfTheParent['value' + index + 'Updated'].connect(item.doSomething)
}
onItemRemoved: {
idOfTheParent['value' + index + 'Updated'].disconnect(item.doSomething)
}
}