public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
* [pve-devel] [PATCH widget-toolkit] cbind: document cbind by adding a small summary and example
@ 2021-10-25  7:26 Dominik Csapak
  2021-10-25  8:59 ` Aaron Lauterer
  2021-10-25  9:05 ` Thomas Lamprecht
  0 siblings, 2 replies; 3+ messages in thread
From: Dominik Csapak @ 2021-10-25  7:26 UTC (permalink / raw)
  To: pve-devel

Explain the use-case, the difference to normal binds, and give an
example that contains all features that can be used with explanations.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 src/mixin/CBind.js | 78 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 78 insertions(+)

diff --git a/src/mixin/CBind.js b/src/mixin/CBind.js
index 8b4153c..71c0b56 100644
--- a/src/mixin/CBind.js
+++ b/src/mixin/CBind.js
@@ -1,3 +1,81 @@
+/*
+ * The Proxmox CBind mixin is intended to supplement the 'bind' mechanism
+ * of ExtJS. In contrast to the 'bind', 'cbind' only act during creation
+ * of the component, not during its lifetime.
+ *
+ * It is used to dynamically set properties of components during their
+ * creation (like a 'nodename' for example), but not later. It is also no
+ * 'double-bind', meaning that a field which has its value 'cbind' will
+ * not change the value of the 'cbind' when the value of the field changes.
+ *
+ * We use it to get a 'declarative' approach to component declaration, even
+ * when we need to set some properties of sub-components dynamically.
+ * This reduces the code in the 'initComponent' and instead we can statically
+ * declare items,buttons,tbars, etc. with the dynamic parts in the 'cbind'.
+ *
+ * It is used like in the following example:
+ *
+ * Ext.define('Some.Component', {
+ *     extend: 'Some.other.Component',
+ *
+ *     // first it has to be enabled
+ *     mixins: ['Proxmox.Mixin.CBind'],
+ *
+ *     // then a base config has to be defined. this can be a function,
+ *     // which has access to the initial config and can store persistent
+ *     // properties, as well as return temporary ones (which only exist during
+ *     // the cbind process)
+ *     // this function will be called before 'initComponent'
+ *     cbindData: function(initialconfig) {
+ *         // 'this' here is the same as in 'initComponent'
+ *         let me = this;
+ *         me.persistentProperty = false;
+ *         return {
+ *             temporaryProperty: true,
+ *         };
+ *     },
+ *
+ *     // if there is no need for persistent properties,
+ *     // it can also simply be an object
+ *     cbindData: {
+ *         temporaryProperty: true,
+ *         // properties itself can also be functions that will be evaluated
+ *         // before replacing the values
+ *         dynamicProperty: (cfg) => !cfg.temporaryProperty,
+ *         // they can be any value
+ *         numericProp: 0,
+ *         // even objects
+ *         objectProp: {
+ *             foo: 'bar',
+ *             bar: 'baz',
+ *         }
+ *     },
+ *
+ *     // you can 'cbind' the component itself, here the 'target' property
+ *     // will be replaced with the content of 'temporaryProperty' (true)
+ *     // before the component is initialized
+ *     cbind: {
+ *          target: '{temporaryProperty}',
+ *     },
+ *
+ *     // you can also 'cbind' values of nested items/etc. like this
+ *     items: [
+ *         {
+ *             xtype: 'checkbox',
+ *             cbind: {
+ *                 // you can negate a property with prefixing '!'
+ *                 value: '{!persistentProperty}',
+ *                 // access to properties of objects can be done like this
+ *                 object: '{objectProp.foo}'
+ *                 // and it can be a function too, when you need more
+ *                 // complicated logic ('dynamic' will get set to 1 here)
+ *                 dynamic: (get) => get('numericProp') + 1,
+ *             },
+ *         },
+ *     ],
+ * });
+ */
+
 Ext.define('Proxmox.Mixin.CBind', {
     extend: 'Ext.Mixin',
 
-- 
2.30.2





^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [pve-devel] [PATCH widget-toolkit] cbind: document cbind by adding a small summary and example
  2021-10-25  7:26 [pve-devel] [PATCH widget-toolkit] cbind: document cbind by adding a small summary and example Dominik Csapak
@ 2021-10-25  8:59 ` Aaron Lauterer
  2021-10-25  9:05 ` Thomas Lamprecht
  1 sibling, 0 replies; 3+ messages in thread
From: Aaron Lauterer @ 2021-10-25  8:59 UTC (permalink / raw)
  To: Proxmox VE development discussion, Dominik Csapak

Sounds good and sums it up nicely :)

I did find two grammatical issues, but that is nit picking on the highest level ;) It is okay and very understandable the way it is.

Reviewed-By: Aaron Lauterer <a.lauterer@proxmox.com>

On 10/25/21 09:26, Dominik Csapak wrote:
> Explain the use-case, the difference to normal binds, and give an
> example that contains all features that can be used with explanations.
> 
> Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
> ---
>   src/mixin/CBind.js | 78 ++++++++++++++++++++++++++++++++++++++++++++++
>   1 file changed, 78 insertions(+)
> 
> diff --git a/src/mixin/CBind.js b/src/mixin/CBind.js
> index 8b4153c..71c0b56 100644
> --- a/src/mixin/CBind.js
> +++ b/src/mixin/CBind.js
> @@ -1,3 +1,81 @@
> +/*
> + * The Proxmox CBind mixin is intended to supplement the 'bind' mechanism
> + * of ExtJS. In contrast to the 'bind', 'cbind' only act during creation
s/act/acts/
s/during/during the/

> + * of the component, not during its lifetime.
> + *
> + * It is used to dynamically set properties of components during their
> + * creation (like a 'nodename' for example), but not later. It is also no
> + * 'double-bind', meaning that a field which has its value 'cbind' will
> + * not change the value of the 'cbind' when the value of the field changes.
> + *
> + * We use it to get a 'declarative' approach to component declaration, even
> + * when we need to set some properties of sub-components dynamically.
> + * This reduces the code in the 'initComponent' and instead we can statically
> + * declare items,buttons,tbars, etc. with the dynamic parts in the 'cbind'.
> + *
> + * It is used like in the following example:
> + *
> + * Ext.define('Some.Component', {
> + *     extend: 'Some.other.Component',
> + *
> + *     // first it has to be enabled
> + *     mixins: ['Proxmox.Mixin.CBind'],
> + *
> + *     // then a base config has to be defined. this can be a function,
> + *     // which has access to the initial config and can store persistent
> + *     // properties, as well as return temporary ones (which only exist during
> + *     // the cbind process)
> + *     // this function will be called before 'initComponent'
> + *     cbindData: function(initialconfig) {
> + *         // 'this' here is the same as in 'initComponent'
> + *         let me = this;
> + *         me.persistentProperty = false;
> + *         return {
> + *             temporaryProperty: true,
> + *         };
> + *     },
> + *
> + *     // if there is no need for persistent properties,
> + *     // it can also simply be an object
> + *     cbindData: {
> + *         temporaryProperty: true,
> + *         // properties itself can also be functions that will be evaluated
> + *         // before replacing the values
> + *         dynamicProperty: (cfg) => !cfg.temporaryProperty,
> + *         // they can be any value
> + *         numericProp: 0,
> + *         // even objects
> + *         objectProp: {
> + *             foo: 'bar',
> + *             bar: 'baz',
> + *         }
> + *     },
> + *
> + *     // you can 'cbind' the component itself, here the 'target' property
> + *     // will be replaced with the content of 'temporaryProperty' (true)
> + *     // before the component is initialized
> + *     cbind: {
> + *          target: '{temporaryProperty}',
> + *     },
> + *
> + *     // you can also 'cbind' values of nested items/etc. like this
> + *     items: [
> + *         {
> + *             xtype: 'checkbox',
> + *             cbind: {
> + *                 // you can negate a property with prefixing '!'
> + *                 value: '{!persistentProperty}',
> + *                 // access to properties of objects can be done like this
> + *                 object: '{objectProp.foo}'
> + *                 // and it can be a function too, when you need more
> + *                 // complicated logic ('dynamic' will get set to 1 here)
> + *                 dynamic: (get) => get('numericProp') + 1,
> + *             },
> + *         },
> + *     ],
> + * });
> + */
> +
>   Ext.define('Proxmox.Mixin.CBind', {
>       extend: 'Ext.Mixin',
>   
> 




^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [pve-devel] [PATCH widget-toolkit] cbind: document cbind by adding a small summary and example
  2021-10-25  7:26 [pve-devel] [PATCH widget-toolkit] cbind: document cbind by adding a small summary and example Dominik Csapak
  2021-10-25  8:59 ` Aaron Lauterer
@ 2021-10-25  9:05 ` Thomas Lamprecht
  1 sibling, 0 replies; 3+ messages in thread
From: Thomas Lamprecht @ 2021-10-25  9:05 UTC (permalink / raw)
  To: Proxmox VE development discussion, Dominik Csapak

On 25/10/2021 09:26, Dominik Csapak wrote:
> Explain the use-case, the difference to normal binds, and give an
> example that contains all features that can be used with explanations.

great, thanks for that!

> Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
> ---
>  src/mixin/CBind.js | 78 ++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 78 insertions(+)
> 
> diff --git a/src/mixin/CBind.js b/src/mixin/CBind.js
> index 8b4153c..71c0b56 100644
> --- a/src/mixin/CBind.js
> +++ b/src/mixin/CBind.js
> @@ -1,3 +1,81 @@
> +/*
> + * The Proxmox CBind mixin is intended to supplement the 'bind' mechanism
> + * of ExtJS. In contrast to the 'bind', 'cbind' only act during creation
> + * of the component, not during its lifetime.

Maybe add something like:

"It's applied only once just before the initComponent method of the component is
 executed, that means you only have a very basic object from the previous steps
 of the constructor available."

> + *
> + * It is used to dynamically set properties of components during their
> + * creation (like a 'nodename' for example), but not later. It is also no
> + * 'double-bind', meaning that a field which has its value 'cbind' will
> + * not change the value of the 'cbind' when the value of the field changes.

That second sentence is rather a bit confusing to me, also not sure if this
mixes double binding and dynamic updates?

"After creation there's no 

> + *
> + * We use it to get a 'declarative' approach to component declaration, even

I'd avoid "we" and rather tell the reader what they can do with it, e.g., here:

You can use it...

> + * when we need to set some properties of sub-components dynamically.
> + * This reduces the code in the 'initComponent' and instead we can statically
> + * declare items,buttons,tbars, etc. with the dynamic parts in the 'cbind'.

missing spaces in the comma-separated list?

and this paragraph shares some redundancy with the former, maybe merge them and
add some info about getter "formulas", boolean negation, and object child element
access here, so that the text doc is a bit more complete and the comments in the
example can be a bit shorter.

Throwing in a sentence about cbind propagation could be also worth it, as it can
be a source of confusion. Maybe something like:

"cbind's are applied recursively on any child object or array elements that have an
.xtype or .cbind property, propagation stops if there is neither of those properties
on a level, even if deeper level would define such properties again. You can add an
empty object as `cbind` property if you want to force the mixin to descend into such
a sub-tree"

(fyi: just wrote that down with not much spell/grammar checking and could be
possibly formulated in a simpler way)

> + *
> + * It is used like in the following example:
> + *
> + * Ext.define('Some.Component', {
> + *     extend: 'Some.other.Component',
> + *
> + *     // first it has to be enabled
> + *     mixins: ['Proxmox.Mixin.CBind'],
> + *
> + *     // then a base config has to be defined. this can be a function,
> + *     // which has access to the initial config and can store persistent
> + *     // properties, as well as return temporary ones (which only exist during
> + *     // the cbind process)
> + *     // this function will be called before 'initComponent'
> + *     cbindData: function(initialconfig) {
> + *         // 'this' here is the same as in 'initComponent'
> + *         let me = this;
> + *         me.persistentProperty = false;
> + *         return {
> + *             temporaryProperty: true,
> + *         };
> + *     },
> + *
> + *     // if there is no need for persistent properties,
> + *     // it can also simply be an object

early new-lined comment

> + *     cbindData: {
> + *         temporaryProperty: true,
> + *         // properties itself can also be functions that will be evaluated
> + *         // before replacing the values
> + *         dynamicProperty: (cfg) => !cfg.temporaryProperty,
> + *         // they can be any value
> + *         numericProp: 0,
> + *         // even objects
> + *         objectProp: {
> + *             foo: 'bar',
> + *             bar: 'baz',
> + *         }
> + *     },
> + *
> + *     // you can 'cbind' the component itself, here the 'target' property
> + *     // will be replaced with the content of 'temporaryProperty' (true)
> + *     // before the component is initialized
> + *     cbind: {
> + *          target: '{temporaryProperty}',
> + *     },
> + *
> + *     // you can also 'cbind' values of nested items/etc. like this
> + *     items: [
> + *         {
> + *             xtype: 'checkbox',
> + *             cbind: {
> + *                 // you can negate a property with prefixing '!'
> + *                 value: '{!persistentProperty}',
> + *                 // access to properties of objects can be done like this

.. can be done with the point notation

> + *                 object: '{objectProp.foo}'
> + *                 // and it can be a function too, when you need more
> + *                 // complicated logic ('dynamic' will get set to 1 here)

Maybe write:
Could be worth to mention that in the text before the example.
"you can also use a getter function, modelled after the formulas of ExtJS's bind"

> + *                 dynamic: (get) => get('numericProp') + 1,
> + *             },
> + *         },
> + *     ],
> + * });
> + */
> +
>  Ext.define('Proxmox.Mixin.CBind', {
>      extend: 'Ext.Mixin',
>  
> 





^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2021-10-25  9:05 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-25  7:26 [pve-devel] [PATCH widget-toolkit] cbind: document cbind by adding a small summary and example Dominik Csapak
2021-10-25  8:59 ` Aaron Lauterer
2021-10-25  9:05 ` Thomas Lamprecht

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal