Мастер расширенной панели вкладок

#javascript #extjs #extjs6

#javascript #extjs #extjs6

Вопрос:

У меня есть довольно продвинутый TabPanel мастер, над которым я работаю, и, похоже, я не могу заставить его работать должным образом. По сути, у меня есть 4 вкладки … каждая вкладка представляет собой свою собственную форму, так как вкладка должна выполнять проверку сама по себе, чтобы она могла определить, нужно ли отключать вкладки справа от нее или должна быть включена следующая вкладка.

Основная проблема, с которой я сталкиваюсь, заключается в том, что не отображаемая вкладка считает ее допустимой, хотя на самом деле ее поле имеет значение allowBlank: false , и оно имеет пустое значение. Тогда есть обратное, где у меня установлено значение, но оно считает его недействительным.

Другая особенность заключается в том, что я должен вызывать this.getViewModel().notify() , когда загружается панель вкладок … в противном случае моя активированная форма считает ее недействительной, когда я проверяю первоначальную действительность… хотя, я считаю, что это как-то связано с привязкой и задержкой, поэтому я могу разобраться с этим прямо сейчас.

Я могу использовать deferredRender: false для решения этой проблемы, но я не хочу, потому что в моем реальном приложении вкладки в каждой из них довольно много, так что это не очень эффективно.

В моей скрипке вы увидите, что включены 3 вкладки, хотя на самом деле должно было быть включено 4 вкладки, поскольку на 3-й вкладке есть данные из ее модели, но вкладка считает, что она недействительна. Поскольку вкладка считает, что она недействительна, она повторно запускает мой метод проверки подлинности, потому что я проверяю, является ли значение isValid ложным (это делается для отключения любой вкладки справа, если текущая вкладка становится недействительной, и пользователь вынужден нажать продолжить, что сделано специально). В консоли:

  • Tab3 считает его недопустимым, что неверно, поскольку для него установлено значение allowBlank: false, но к нему привязано значение
  • Tab4 будет считать, что это допустимо, что неверно, потому что для него установлено значение allowBlank: false и не имеет значения

У кого-нибудь есть понимание? Я делаю это ужасно неправильно?

Ответ №1:

Это происходит потому, что модели представления и привязки не выполняют то, что вы думаете, что они делают.

Сначала — когда вы создаете поле, подобное этому:

 { fieldLabel: 'Value3', xtype: 'textfield', name: 'value2', allowBlank: false,
  bind: { value: '{model1.value2}' }
}
  

изначально поле создается без значения. Это потому, что вы не определили какое-либо значение — вы его привязали. И привязка не вступает в силу немедленно. По соображениям производительности он обычно не будет привязан до тех пор, пока вкладка не будет отображена (именно поэтому для вас не работает отсрочка рендеринга)

Конечным результатом этого является то, что при проверке правильности Tab 3 происходит сбой, поскольку значения еще не привязаны. Вы можете увидеть это более четко, если измените инструкцию log в строке 24 следующим образом:

 console.log(form.owner.title, form.getValues(), form.owner.rendered, isValid)
  

С этим изменением при первом отображении панели вкладок вы получаете этот вывод (без комментариев):

 afterrender // triggers the view model to notify.
activate
checking
tab1 Object {value: "blah"} true true  // Value bound because it was rendered.
tab2 Object {value: ""} false true
tab3 Object {value2: ""} false false // Value not bound because it is not rendered
checking
tab4 Object {} false true // No properties yet...
  

Обратите внимание, что если вы не вызываете this.getViewModel().notify() , то вы получите этот вывод:

 afterrender
activate
checking
tab2 Object {} false true
tab3 Object {} false true
tab4 Object {} false true
tab1 Object {value: "blah"} true true
  

Обратите внимание на разные порядки.

Итак, что здесь происходит? Ну, во-первых, отдельные формы на вкладках не имеют данных, пока не будут привязаны значения полей. Без полей они считаются действительными.

Когда вы вызываете isValid , он принудительно определяет поля, но они все еще не привязаны. Таким образом, они не имеют значения, и в случае tab3 это делает его недействительным. Поскольку tab3 недействителен (пока нет привязки к данным), вкладка 4 не включена.

Если вы не вызываете viewModel.notify() , то это tab1 , который еще не привязан к данным во время первого вызова checkValidity() . Таким образом, он недействителен (в нем есть поля, но нет значений), А tab2 и т. Д. Не Включены.

Достоверность в конечном итоге выясняется, но вы проверяете состояние только при изменении значения true на false, а не false на true. Что дает поведение, которое вы видите.

Как это исправить? Вероятно, есть несколько способов. Вероятно, наиболее эффективным является получение значений из ViewModel во время initComponent для панели и явное присвоение их полям при их создании. Таким образом, они изначально создаются с правильным состоянием и, таким образом, проходят проверку достоверности.

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

1. Спасибо, что прошли через весь процесс отладки … это то, что, как я понял, происходит. Но вот в чем дело: форма не должна быть допустимой, если в ней есть поле с allowBlank: false и пустое значение … вот что действительно странно. По замыслу это должно означать, что оно недействительно, поэтому tab4 также должно быть недействительным. Проблема с заменой false на true заключается в том, что он срабатывает много раз (из-за вызова isValid), и это нежелательное поведение, поскольку другие вкладки могут стать активированными после того, как вкладка стала недействительной.

2. Форма недопустима с полем, которое не допускает пустых значений, когда оно имеет пустое значение. Вот почему tab3 недействителен. Проблема в том, что в форме вообще нет полей, пока она не будет собрана и отображена. И форма с нулевыми полями допустима.

3. Роберт, используя эту логику, tab3 еще не отрисован, поэтому он все еще должен быть действительным.

4. Посмотрите на отладку. Отображается Tab1. Это вызывает вызов checkValidity() . Допустима таблица Tab1. Таким образом, tab2 проверяется на правильность. Это загружается в форме, но не в ViewModel. Это нормально для tab2, поэтому оно допустимо, а tab3 проверяется. Tab3 загружен в (без ViewModel) и недействителен — в нем есть поля, но нет данных. Это делает tab4 отключенным. Затем создается экземпляр Tab4, который действителен до тех пор, пока не получит поля, чего не будет, пока это не потребуется (например, путем рендеринга или вызова isValid() для него). Модели представления появляются чуть позже, делая все действительным, но вы не сбрасываете отключенное состояние.

5. Визуализация — это одно событие, которое будет загружено в поля формы. Вызов isValid() — это другое. Главное здесь в том, что в вашей форме еще нет данных — исправьте это, и ваши проблемы исчезнут.