Ext JS - 将多个表单字段绑定到模型的一个字段

时间:2017-07-25 08:37:50

标签: extjs extjs6 extjs6-classic

我有一个带有十六进制色域的模型。用户可以通过3个单独的数字字段将其编辑为rgb。我正在尝试将字段绑定到这些组件,但我不知道该怎么做。我尝试将它们放入容器中并将容器绑定到字段。但是,当更改数字字段时,不会调用我的setValue。

我想我可以在数字字段中添加听众,但我希望有更好的方法可以解决这个问题。

https://fiddle.sencha.com/#view/editor&fiddle/23t2

2 个答案:

答案 0 :(得分:0)

仅在表单字段上调用

setValue。表单字段由config isFormField: true表示。但请注意,setValue不是表单字段上唯一的预期函数;还有其他几十个人(例如getValuegetModelValueisValid,...)。

因此,我总是使用hiddenfield聚合其他表单字段,而不是container,然后我使用更改侦听器来保持hiddenfield和其他字段的同步(绑定应该也可以,但我们的应用程序仍然是MVC)。我还用

注释其他字段
excludeForm: true,
submitValue: false,

确保未提交值并且不会影响"脏"形式的状态。

答案 1 :(得分:0)

我做了一些改变。它适用于两种情况,

  1. 如果用户从颜色名称(textfield)更改,则RGB将更改。
  2. 如果用户将从数字字段更改而不是颜色名称(textfield)将更改。
  3. 在您的sencha fiddle

    中试用此代码
    Ext.create({
        xtype: 'viewport',
        renderTo: Ext.getBody(),
    
        viewModel: {
            data: {
                theColor: {
                    name: 'Blue',
                    hex: '3366CC'
                }
            },
            formulas: {
                containerValue: {
                    bind: '{theColor.hex}',
                    get: function (value) {
                        return {
                            hex: value
                        };
                    },
                    set: function (value) {
                        this.set('theColor.hex', value.hex);
                    }
                }
            }
        },
    
        items: [{
            region: 'center',
            xtype: 'form',
            bodyPadding: 10,
            height: 300,
    
            fieldDefaults: {
                labelWidth: 90,
            },
    
            items: [{
                xtype: 'component',
                width: 30,
                height: 30,
                bind: {
                    style: {
                        background: '#{theColor.hex}'
                    }
                }
            }, {
                xtype: 'textfield',
                fieldLabel: 'Name',
                bind: '{theColor.name}',
                listeners:{
                    blur:function(textfield,e,eOpts){
                        var viewModel = textfield.up('viewport').getViewModel();
                            colorName = textfield.getValue(),
                            hex = colorToHex(colorName);
                        viewModel.set('theColor',{
                         name: colorName,
                         hex: hex
                        });
                        function colorToRGBA(color) {
                            // Returns the color as an array of [r, g, b, a] -- all range from 0 - 255
                            // color must be a valid canvas fillStyle. This will cover most anything
                            // you'd want to use.
                            // Examples:
                            // colorToRGBA('red')  # [255, 0, 0, 255]
                            // colorToRGBA('#f00') # [255, 0, 0, 255]
                            var cvs, ctx;
                            cvs = document.createElement('canvas');
                            cvs.height = 1;
                            cvs.width = 1;
                            ctx = cvs.getContext('2d');
                            ctx.fillStyle = color;
                            ctx.fillRect(0, 0, 1, 1);
                            return ctx.getImageData(0, 0, 1, 1).data;
                        }
    
                        function byteToHex(num) {
                            // Turns a number (0-255) into a 2-character hex number (00-ff)
                            return ('0'+num.toString(16)).slice(-2);
                        }
    
                        function colorToHex(color) {
                            // Convert any CSS color to a hex representation
                            // Examples:
                            // colorToHex('red')            # '#ff0000'
                            // colorToHex('rgb(255, 0, 0)') # '#ff0000'
                            var rgba, hex;
                            rgba = colorToRGBA(color);
                            hex = [0,1,2].map(
                                function(idx) { return byteToHex(rgba[idx]); }
                                ).join('');
                            return hex;
                        }
                    }
                }
            }, {
                xtype: 'container',
    
                setValue: function (value) {
                    const hex = value.hex || '000000';
    
                    const red = parseInt(hex.substr(0, 2), 16);
                    const green = parseInt(hex.substr(2, 2), 16);
                    const blue = parseInt(hex.substr(4, 2), 16);
    
                    const items = this.query('');
    
                    items[0].setValue(red);
                    items[1].setValue(green);
                    items[2].setValue(blue);
                },
    
                bind: {
                    value: '{containerValue}',
                },
    
                defaults: {
                    xtype: 'numberfield',
                    maxValue: 255,
                    minValue: 0,
                    allowBlank: false,
                    width: 175,
                    listeners:{
                        change:function(numberfield){
                            if(numberfield.hasFocus){
                                var viewModel = numberfield.up('viewport').getViewModel(),
                                    items = this.up().query(''),
                                    red =  items[0].getValue() || 0,
                                    green = items[1].getValue() || 0,
                                    blue = items[2].getValue() || 0,
                                    hex = rgbToHex(red,green,blue);
                                viewModel.set('theColor',{
                                 name: hex,//For hex to color name you have to search for that, here I am giving hax color.
                                 hex: hex
                                });
                                function componentToHex(c) {
                                    var hex = c.toString(16);
                                    return hex.length == 1 ? "0" + hex : hex;
                                }
    
                                function rgbToHex(r, g, b) {
                                    return componentToHex(r) + componentToHex(g) + componentToHex(b);
                                }
                            }
                        }
                    }
                },
    
                items: [{
                    fieldLabel: 'R',
                }, {
                    fieldLabel: 'G',
                }, {
                    fieldLabel: 'B',
                }]
            }]
        }]
    });