Как узнать, были ли изменены данные в viewmodel?

#extjs #listener #viewmodel #bind

#extjs #прослушиватель #viewmodel #привязка

Вопрос:

У меня есть 3 таких поля:

 
   {
    name: 'firstName',
    fieldLabel: 'First name',
    bind: '{person.firstName}',
    xtype: 'textfield',
    allowBlank: false,
    listeners: {
        blur : {
           buffer : 1000,
           fn : 'detectGender'
         },
        }
    },
{
    name: 'middleName',
    fieldLabel: 'Middle name',
    bind: '{person.midleName}',
    xtype: 'textfield',
    allowBlank: true,
    listeners: {
        blur : {
           buffer : 1000,
           fn : 'detectGender'
         },
        }
    },
{
    name: 'lastName',
    fieldLabel: 'Last name',
    bind: '{person.lastName}',
    xtype: 'textfield',
    allowBlank: true,
    listeners: {
        blur : {
           buffer : 1000,
           fn : 'detectGender'
         },
        }
    },
 

И у меня есть функция для определения пола пользователя:

  detectGender: function () {
        const vm = this.getViewModel()
        const firstName = vm.get('person.firstName');
        const lastName = vm.get('person.lastName');
        
        const personName = `${firstName ? firstName : ' '}${middleName ? middleName : ' '}${lastName ? lastName : ' '}`

        if (firstName) {
      
             //ajax request to server with data: personName 
             // personName migth be  SarahSmith, or Sarah, or SarahEllen, or SarahEllenSmith

        }
    },
 

Это работает, но моя проблема в том, что функция ‘detectGender’ выполняется все три раза, если все эти поля заполнены. И мой сервер возвращает три ответа. Но мне нужно запустить это только один раз. Может быть, есть какой-то способ создать событие для прослушивания viewmodel при изменении имени пользователя?
Или какие-либо идеи о том, как отправить имя пользователя из трех полей только один раз?
Надеюсь, я был достаточно ясен… Пожалуйста, любая помощь

Комментарии:

1. Просто поставьте галочку, чтобы 3 имени не были пустыми. Что-то вроде if(!Ext.isEmpty(FirstName) amp;amp; !Ext.isEmpty(MiddleName) amp;amp; !Ext.isEmpty(LastName) { ОТПРАВИТЬ ЗАПРОС AJAX}

Ответ №1:

Я думаю, что комментарий Артура, вероятно, самый простой способ решить проблему.

Однако вот еще пара вариантов.

Opt1 — Вы можете поместить каждое из полей имени в «родительское» и прослушать событие «размытие» в родительском. В примере sencha fiddle посмотрите на код «Opt1», который я настроил с помощью «fieldcontainer». Поскольку в контейнере нет события «размытия», используется событие «focusleave». Я думаю, что из моих двух вариантов этот был бы лучшим, так как он дает вам хорошее представление о том, что пользователь закончил вводить имя.

                 // Opt 1: Detect "blur" on higher level element
                // so you know user is done
                xtype: 'fieldcontainer',
                layout: 'hbox',
                fieldLabel: 'Name',
                listeners: {
                    // "Opt1: blur equivilent" for a container
                    focusleave: 'detectGender'
                },
                items: [{
                    name: 'firstName',
                    emptyText: 'First',
                    bind: '{person.firstName}',
                    xtype: 'textfield',
                    allowBlank: false
                }, {
                    name: 'middleName',
                    emptyText: 'Middle',
                    bind: '{person.middleName}',
                    xtype: 'textfield',
                    allowBlank: true
                }, {
                    name: 'lastName',
                    emptyText: 'Last',
                    bind: '{person.lastName}',
                    xtype: 'textfield',
                    allowBlank: true
                }]
            }
 

Opt2 — Вы вызвали прослушивание данных ViewModel. Я привел пример этого, но это в основном событие «изменения», поэтому вы будете получать событие каждый раз, когда кто-то вводит букву в поле, что приводит к аналогичной проблеме, с которой вы столкнулись сейчас. Я сделал пример для развлечения, с регулируемой функцией, чтобы помочь задержке, но я думаю, что в конечном итоге вы слишком часто вызываете сервер, поскольку, в отличие от приведенного выше, вы не знаете, когда кто-то «закончил» вводить имя.

При этом используется bindings конфигурация ViewController, что удобно для ручного вызова ViewModel.bind() , с помощью которого вы можете «прослушивать» данные ViewModel.

Вот скрипка, надеюсь, это не слишком запутанно, имея оба примера в одном.

Скрипка Сенча

Комментарии:

1. Большое вам спасибо! Мне понравилась идея использования привязки. Но я немного изменил привязку модели в своей функции инициализации следующим образом: this.getViewModel().bind(‘{Полное имя}’, Доб. Функция.createBuffered(this.detectGender, 1000, this), this); Функция createBuffered позволила мне отправить буферизованный запрос.