#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 позволила мне отправить буферизованный запрос.