Изменение ExtJS 3.4 устанавливает одно и то же значение сразу для нескольких полей DisplayFields

Работая в ExtJS 3.4, мне нужно показать некоторые значения в нескольких строках (макет формы). Каждая строка выглядит так:

<label> <field> <unit of measure>

Где <unit of measure> - это DisplayField с нередактируемым вручную текстом, указывающим единицу измерения (например, литры, метры, ...).

Мне нужно добавить механизм для переключения между единицами измерения, например. кнопка. В идеале я хотел бы щелкнуть эту кнопку, изменить одно значение (или вызвать только один метод установки) и увидеть новое значение в частях моего интерфейса <unit of measure>. Другими словами, мне бы хотелось, чтобы мне не приходилось сохранять и циклически перебирать серию ссылок на несколько объектов DisplayField.

До сих пор я пытался создать экземпляр и сохранить ссылку на один DisplayField и вставить его в несколько строк, чтобы я мог вызвать field.setValue(...), например:

var dispF = new Ext.form.DisplayField({
    value:'liters'
});
var row1 = new Ext.form.CompositeField({
    ...
    items: [<some numberfield 1>, dispF]
    ...
});
var row2 = new Ext.form.CompositeField({
    ...
    items: [<some numberfield 2>, dispF]
    ...
});
//Calling this by some means
dispF.setValue('m^3');

Однако dispF будет отображаться только на последнем созданном элементе, который его использует (в данном случае row2).

Я также пробовал следующее:

var t = 'liters';
var dispF = {
    xtype:'displayfield',
    value:t
};
var row1 = new Ext.form.CompositeField({
    ...
    items: [<some numberfield 1>, dispF]
    ...
});
var row2 = new Ext.form.CompositeField({
    ...
    items: [<some numberfield 2>, dispF]
    ...
});
...
//Calling this by some means
t='m^3';

В этом случае «литры» отображаются в правильном положении для всех строк, но не меняются на «m ^ 3».

Я бы не хотел использовать для этого сетку.

Обработка каждого поля вручную может быть немного сложной, так как строк много, и на самом деле они могут содержать более одного поля и группы единиц измерения, в то время как их хранение в массивах затруднит чтение кода тем, кто пришел после (code здесь необходимо учитывать удобочитаемость).

Есть ли способ обновить DisplayField в каждой строке с помощью выполнение только одной операции (например, назначение, вызов setValue (), ...) вместо того, чтобы объявлять и создавать экземпляр DisplayField для каждой строки, а затем вызывать setValue () для каждой из них?

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
158
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Следующее решение может вам помочь. Отличие заключается в том, что значения изменяются с помощью вызова одна пользовательская функция, а не с помощью одна операция. Но с этим решением вам не нужно хранить ссылку для каждого объекта displayfield или хранить их в массиве.

Шаги в решении: создать подкласс displayfield и определяемую пользователем функцию:

Ext.onReady(function(){
    // Class definition.
    TestDisplayField = Ext.extend(Ext.form.DisplayField, {
        constructor: function(config) {
            TestDisplayField.superclass.constructor.call(this, config);
        },
    });
    Ext.reg('testdisplayfield', TestDisplayField);

    // Global setter function.
    function setTestDisplayFieldValues(container, value, xtype) {
        var items = container.items;
        for (var i = 0; i < items.length; i++) {
            var component = items.get(i);
            if (Ext.isDefined(component.items)) {
                setTestDisplayFieldValues(component, value, xtype)
            } else {
                if (component.xtype == xtype) {
                    component.setValue(value);
                }
            }
        }
    };

    // Components. 
    // Here are 'displayfield' and 'tesdisplayfield' components just for test.
    var row1 = new Ext.form.CompositeField({
        items: [
            {xtype: 'numberfield', width: 50}, {xtype: 'displayfield', value : 'liters', width: 100},
            {xtype: 'numberfield', width: 50}, {xtype: 'displayfield', value : 'liters', width: 100},
            {xtype: 'numberfield', width: 50}, {xtype: 'testdisplayfield', value : 'liters', width: 100},
            {xtype: 'numberfield', width: 50}, {xtype: 'testdisplayfield', value : 'liters', width: 100}
        ]
    });
    var row2 = new Ext.form.CompositeField({
        items: [
            {xtype: 'numberfield', width: 50}, {xtype: 'displayfield', value : 'liters', width: 100},
            {xtype: 'numberfield', width: 50}, {xtype: 'displayfield', value : 'liters', width: 100},
            {xtype: 'numberfield', width: 50}, {xtype: 'testdisplayfield', value : 'liters', width: 100},
            {xtype: 'numberfield', width: 50}, {xtype: 'testdisplayfield', value : 'liters', width: 100}
        ]
    }); 

    // Form 
    Ext.create(
        {
        xtype: 'form',
        id: 'testform',
        renderTo: Ext.getBody(),
        title: 'Image', 
        width: 600,
        height: 300,
        layout: 'vbox',
        items: [
            row1,
            row2
        ],
        buttons: [
            {
            text: 'Set value',
            handler: function(button) {
                // Change the values of all 'testdisplayfield' components.
                // Here you can use 'displayfield' as xtype if all you components are 'displayfield' and must be changed.
                // In this case it's not necessary to define 'TestDisplayField' class.
                setTestDisplayFieldValues(Ext.getCmp('testform'), 'm^3', 'testdisplayfield');
            }
            }
        ]
    });
});

Примечания:

Протестировано с ExtJS 3.4

Я подумал о добавлении прослушивателя onRender в конфигурацию DisplayField, чтобы добавить каждое поле в массив, а затем циклически перебирать этот массив, когда мне нужно изменить значения (таким образом, массив гарантированно будет содержать только элементы, экземпляры которых созданы из этой конфигурации). Однако это звучит тяжело с точки зрения слушателей, которых нужно было бы уволить только один раз. Предлагаемое решение кажется более компактным, и даже при рекурсивном исследовании DOM-дерева оно не выглядит слишком тяжелым (плюс, пользователь не собирается менять единицу измерения каждые полсекунды). Принято как правильный ответ. Спасибо.

Kurobara 10.09.2018 16:58

Другие вопросы по теме