Attaching a custom event to an existing widget?

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Attaching a custom event to an existing widget?

LoneSurvivor
This post has NOT been accepted by the mailing list yet.
Hi all,

this is my first post to the qooxdoo-forum. Since a few weeks I'm evaluating qooxdoo and what I saw so far was really cool.

I'll try to describe my problem:

I do have a property that's called gameMoney (int). If this value changes, I want a label to get updated with this value. First I configured an apply like this:

properties: {        
 gameMoney: {
  check: "Number",
   init: 0,
   apply: "updateMoney"
  }
},
members: {
 updateMoney : function(value){
  this.__infoBarLabelMoney.setValue(value);
  }
}

This works great but doesn't seems the right way to me. Why should a primitive value should have knowledge of the objects that works with it. I would find it a more cool way if the variable sends an event if it's changed and all using objects would react to that.

So I followed the manual from this page which seemed to be the right way:

http://manual.qooxdoo.org/current/pages/core/understanding_properties.html#change-events

I changed the property-configuration to the following:

gameMoney: {
 check: "Number",
 init: 0,
 event: "changeGameMoney"
}

and added the listener to the label-object:

this.__infoBarLabelMoney = new qx.ui.basic.Label("Geld: " + this.getGameMoney() + " $");
this.__infoBarLabelMoney.addListener("changeGameMoney", function (e) {
 this.setValue("Geld: " + e.getData() + " $");
});

But the problem is, that I receive the following error message: "[...] There is no event handler for the event 'changeGameMoney' on target 'qx.ui.basic.Label [...]"

Okay, read again the manual and found this sentence: "In order to get notified of any value changes, you simply attach an event listener to the object instance containing the property in question."

That made sense to me: only the containing class where both the property and the label are used can work with the event. So if I add something like this to the constructor of my containing class, it works:

this.addListener("changeGameMoney", function (e) {
 this.__infoBarLabelMoney.setValue("Geld: " + e.getData() + " $");
}, this);

But is this the right way? Wouldn't it be better, to register this type of event somehow to the infoBarLabelMoney-label? Or do I have to create a custom Label that inherits from Label and registers the event-type with

events : {
 "changeGameMoney" : "qx.event.type.Data"
}

?

Can somebody tell me about the best practice in qooxdoo for handling this?

Best wishes and regards
LoneSurvivor
Reply | Threaded
Open this post in threaded view
|

Re: Attaching a custom event to an existing widget?

LoneSurvivor
Or is it possible to bind a widget to a property like a number? In the examples on this page (http://manual.qooxdoo.org/current/pages/data_binding/single_value_binding.html) are between widgets only.
Reply | Threaded
Open this post in threaded view
|

Re: Attaching a custom event to an existing widget?

John Spackman-3
You can’t directly bind to a number, but you can create a property in your own class and bind to that; this is a useful technique because if you want to do something when the value changes, your property can have its own “apply” method.

John




On 04/01/2016, 19:29, "LoneSurvivor" <[hidden email]> wrote:

>Or is it possible to bind a widget to a property like a number? In the
>examples on this page
>(http://manual.qooxdoo.org/current/pages/data_binding/single_value_binding.html)
>are between widgets only.
>
>
>
>--
>View this message in context: http://qooxdoo.678.n2.nabble.com/Attaching-a-custom-event-to-an-existing-widget-tp7587908p7587912.html
>Sent from the qooxdoo mailing list archive at Nabble.com.
>
>------------------------------------------------------------------------------
>_______________________________________________
>qooxdoo-devel mailing list
>[hidden email]
>https://lists.sourceforge.net/lists/listinfo/qooxdoo-devel



------------------------------------------------------------------------------
_______________________________________________
qooxdoo-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/qooxdoo-devel
Reply | Threaded
Open this post in threaded view
|

Re: Attaching a custom event to an existing widget?

LoneSurvivor
Hi John,

thanks for your answer.
I'm not quite sure, if I understand you correctly. My problem is, that I have a number-property in my root widget that holds some money-value. This money-value should be shown in a few ddefault label-widgets that are added to some deeper windows. You know, click a button, a window opens, there's another button that opens a subwindow and then there is a label that shows that money-value.
And there are some more subwindows that opens on other buttons that maybe also show that money-value.

So there are different places in different levels of hiearchy which must be updated for the changed value. So should I bind those labels all together with a label added to the root-widget that gets updated by the initial changeEvent and the rest get's automatically updated by the bindings?

Thank you in advance
LoneSurvivor
Reply | Threaded
Open this post in threaded view
|

Re: Attaching a custom event to an existing widget?

John Spackman-3
Hi

This is easy so long as by “I have a number-property” you mean that you have an actual Qooxdoo property in your root widget, for example if you have something like this in your root widget class:

qx.Class.define("my.RootWidget", {

  extend: qx.ui.core.Widget,

  

  properties: {

    numberValue: {

      init: 0,

      nullable: false,

      check: "Number",

      event: "changeNumberValue"

    }

  },

  members: {

    // ... snip ...

  }

});



You can then write code in RootWidget such as:

    var dlg = new my.MyDialog();

    this.bind("numberValue", dlg, "numberValue");


And

qx.Class.define("my.MyDialog", {

  extend: qx.ui.window.Window,

  

  properties: {

    numberValue: {

      init: 0,

      nullable: false,

      check: "Number",

      event: "changeNumberValue"

    }

  },

  

  construct: function() {

    this.base(arguments);


    var lbl = new qx.ui.basic.Label()

    this.bind("numberValue", lbl, "value", { 

      convert: function(data) { 

        return "" + data; 

      } 

    });

  }

});


This approach lets you hide the UI implementation of MyDialog from the RootWidget, so all your code is thinking about is the numberValue property itself.  If MyDialog pops up another dialog, just pass it on in the same way.

Of course if numberValue is not the only property it can become tiresome binding lots of variables just for them to be passed on to something else so you could refactor this as:

qx.Class.define("my.MyData", {

  extend: qx.core.Object,

  

  properties: {

    numberValue: {

      init: 0,

      nullable: false,

      event: "changeNumberValue"

    }

  }

});


qx.Class.define("my.RootWidget", {

  extend: qx.ui.core.Widget,

  

  properties: {

    myData: {

      init: null,

      nullable: true,

      check: "my.MyData",

      event: "changeMyData"

    }

  },

  

  construct: function() {

    var dlg = new my.MyDialog();

    this.bind("myData", dlg, "myData");

  },

  

  members: {

    // ... snip ...

  }

});


Then you can add values and methods by just amending MyData

Note that this is only possible if you use Qooxdoo properties – if you just declare a private member variable like the below code you cannot bind to it:

  members: {

    __numberValue: 0,

    // ... snip..

  }


John

On 06/01/2016, 11:15, "LoneSurvivor" <[hidden email]> wrote:

Hi John,

thanks for your answer.
I'm not quite sure, if I understand you correctly. My problem is, that I
have a number-property in my root widget that holds some money-value. This
money-value should be shown in a few ddefault label-widgets that are added
to some deeper windows. You know, click a button, a window opens, there's
another button that opens a subwindow and then there is a label that shows
that money-value.
And there are some more subwindows that opens on other buttons that maybe
also show that money-value.

So there are different places in different levels of hiearchy which must be
updated for the changed value. So should I bind those labels all together
with a label added to the root-widget that gets updated by the initial
changeEvent and the rest get's automatically updated by the bindings?

Thank you in advance
LoneSurvivor



--
Sent from the qooxdoo mailing list archive at Nabble.com.

------------------------------------------------------------------------------
_______________________________________________
qooxdoo-devel mailing list


------------------------------------------------------------------------------

_______________________________________________
qooxdoo-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/qooxdoo-devel
Reply | Threaded
Open this post in threaded view
|

Re: Attaching a custom event to an existing widget?

LoneSurvivor
Hi John,

thank you for your answer, this was exactly what I was looking for. Also for the example with the myData-object which would become my next hurdle. Thank you very much!

I noticed one little bug in your code:

this.bind("numberValue", lbl, "value", {
 convert: function(data) {
 return "" + data;
}

It must be "converter" or else the function will not be called.

But once again: thank you very much!

Greetings
LoneSurvivor
Reply | Threaded
Open this post in threaded view
|

Re: Attaching a custom event to an existing widget?

John Spackman-3
Ah yes, well spotted :)

Regards
John





On 07/01/2016, 20:51, "LoneSurvivor" <[hidden email]> wrote:

>Hi John,
>
>thank you for your answer, this was exactly what I was looking for. Also for
>the example with the myData-object which would become my next hurdle. Thank
>you very much!
>
>I noticed one little bug in your code:
>
>this.bind("numberValue", lbl, "value", {
> convert: function(data) {
> return "" + data;
>}
>
>It must be "converter" or else the function will not be called.
>
>But once again: thank you very much!
>
>Greetings
>LoneSurvivor
>
>
>
>--
>View this message in context: http://qooxdoo.678.n2.nabble.com/Attaching-a-custom-event-to-an-existing-widget-tp7587908p7587937.html
>Sent from the qooxdoo mailing list archive at Nabble.com.
>
>------------------------------------------------------------------------------
>_______________________________________________
>qooxdoo-devel mailing list
>[hidden email]
>https://lists.sourceforge.net/lists/listinfo/qooxdoo-devel



------------------------------------------------------------------------------
_______________________________________________
qooxdoo-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/qooxdoo-devel