alex_lip
31 октября 2018 г. 18:08

Динамическая подмена моделей для ListView

Есть ListView для которого я меняю модели, которые заполняю из SqlLite. В принципе все работает, но кое-что непонятно.

Пример - при клике на текущей строке ListView у меня срабатывает следующая функция


  1. MouseArea {
    onClicked: { EsdDb.readDataSea_phones(parent_officeid);}
    }

где

  1. function readDataSea_phones(m_usersid) {
  2. seaPhones.clear();
  3.  
  4. if(!db) { return; }
  5.  
  6. db.transaction( function(tx) {
  7. var sql_text1='select surname, name, middle_name, name_rec, usersid, staffid, name_sokr, officeid, av_path from all_tel where usersid = '+'\'' +m_usersid +'\'';
  8.  
  9. var result = tx.executeSql(sql_text1);
  10. for(var i = 0; i < 1; i++) {
  11. seaPhones.append({phone:result.rows.item(i).surname+" "+ result.rows.item(i).name+" "+result.rows.item(i).middle_name, tip_n:"" ,usersid: result.rows.item(i).usersid, av_path: result.rows.item(i).av_path});
  12. }
  13. } );
  14.  
  15. db.transaction( function(tx) {
  16. var sql_text='select phone, tip_n, usersid from all_phones where usersid = '+'\'' +m_usersid +'\'';
  17. var result = tx.executeSql(sql_text);
  18. for(var i = 0; i < result.rows.length; i++) {
  19. seaPhones.append({phone:result.rows.item(i).phone, tip_n: result.rows.item(i).tip_n, usersid: result.rows.item(i).usersid, av_path: ""});
  20. }
  21. } );
  22. root_i.model_name="seaPhones";
  23. view_all_tree.model=seaPhones;
  24.  
  25. }



В этом скрипте я выполняю запрос к базе данных и подменяю текущую модель для ListView на другую. Все работает. Но я в консоле вижу, что QML сначала рефрешит старую модель, а уже затем отображает новую. У меня генерятся ошибки вывода на экран типа qrc:/content/TelSpr.qml:759 : ReferenceError: phone is not defined , и действительно - поле phone у меня описано в той модели, которую я присваиваю в скрипте, А не в той которая текущая была. Но скрипт то отработал. Я вижу по логам, что скрипт отработал, потом ошибки предыдущего отображения, потом нормальный вывод на экран той модели, которую я заполнил в скрипте.


данные модели я вывожу так


  1. Text {
  2. id:text_tree
  3. padding : 5
  4. width: parent.width
  5. renderType: Text.NativeRendering
  6. font.pixelSize: dp(19);
  7. font.bold: true
  8. textFormat: Text.StyledText
  9. wrapMode: "Wrap"
  10.  
  11. function model_field(field)
  12. {
  13. if(field ==='myModel_All_tree'){
  14. return name_office
  15. }
  16. if(field ==='myModel_All_tel'){
  17. return fio
  18. }
  19. if(field ==='myModel_All_phones'){
  20. return phone
  21. }
  22. if(field ==='seaModel_id'){
  23. return name_sokr+" "+name_rec
  24. }
  25. if(field ==='seaModel'){
  26. return name_sokr+" "+name_rec
  27. }
  28. if(field ==='seaPhones'){
  29. return phone+" "+tip_n
  30. }
  31. if(field ==='seaTree'||field ==='seaTree_lvl_1'||field ==='seaTree_lvl_2'||field ==='seaTree_lvl_3'){
  32. return name_office
  33. }
  34. else
  35. {
  36. return ""
  37. }
  38. }
  39. text: model_field(root_i.model_name)
  40. }
  41. }



То есть в зависимости от того какая модель - выводятся соотв. поля. Еще раз повторюсь - на вид все работает. Но мне не нравится то что происходит в логах.











3

Вам это нравится? Поделитесь в социальных сетях!

4
Evgenii Legotckoi
  • 31 октября 2018 г. 19:00

Думаю, что проблема вот в этом.

root_i.model_name="seaPhones";

view_all_tree.model=seaPhones;

Вернее в местоположении этих строчек.

Сначала установите имя модели, а потом уже данные с полем phone начинайте добавлять. Скорее всего перерисовка выпонляется при каждом добавлении данных в таблицу, то есть при каждом append .

А вообще, не хорошо в представлении писать невалидные поля. Благо, что это JavaScript.




    alex_lip
    • 31 октября 2018 г. 19:08
    • (ред.)

    пробовал. В этом случае сначала идет рефреш старой модели, потом скрипт, потом отображение новой. Но ошибки из-за рефреша все равно идут. 

    То есть похоже рефреш происходит в момент выполнения функции view_all_tree.model=seaPhones;


    В принципе я могу все модели привести к набору одинаковых полей. Тогда ошибок не будет. Но почему происходит рефреш ListView с привязкой к старой модели, когда там уже новые данные. Вот вопрос

      Evgenii Legotckoi
      • 31 октября 2018 г. 19:26

      Я бы ещё попробовал написать или два разных представления, или два разных делегате, и менял бы делегаты в зависимости от устанавливаемой модели.

        alex_lip
        • 1 ноября 2018 г. 12:48
        • Ответ был помечен как решение.

        В делегатах слишком много кода. Я просто понаписал фиктивных полей в моделей - чтобы не было ошибок. И все оставил как есть.

          Комментарии

          Только авторизованные пользователи могут публиковать комментарии.
          Пожалуйста, авторизуйтесь или зарегистрируйтесь