[pve-devel] [PATCH widget-toolkit] cbind: document cbind by adding a small summary and example

Thomas Lamprecht t.lamprecht at proxmox.com
Mon Oct 25 11:05:42 CEST 2021


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 at 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',
>  
> 






More information about the pve-devel mailing list