Подтупливаем....

Иногда бывает какая то простая задача, над которой ты сидишь по пол дня и не сможешь её решить, а ответ оказывается рядом.
Пример: Есть JSON из которого мы сделали объект:

Код QML:
  1. var object = JSON.parse(answer);
Тут всё просто, но ветки(?) или как там его у JSON`а именованные. Короче говоря языком PHP вместо этого:
Код PHP:
  1. answer[] = 0;
  2. answer[] = 1;
  3. answer[] = 2
Мы имеем:

Код PHP:
  1. answer["zero"] = 0;
  2. answer["one"] = 1;
  3. answer["two"] = 2
И при попытке перебрать все объекты в QML через forEach мы влетаем в весёлую ошибку:
TypeError: Property 'forEach' of object [object Object] is not a function
Тобиж в именнованных объектах у нас не работает метод forEach так же как и обрашение по порядку, тоесть вариант object[0] и так далее не проходит. Что же делать? Решение вот такое нашёл. Работает, эффективность не проверял.

Код QML:
  1. for(var key in object)
  2. {
  3. if(object.hasOwnProperty(key))
  4. {
  5. itemModel.append(object[key])
  6. }
  7. }
Криво? Очень. Но работает.
Комментарии (8)
  1. Вопрос. А зачем лишний раз проверять на наличие свойства, если в данном случае key будет всегда соответствовать существующему ключу? И еще. Есть функция Object.keys(объект), которая возвращает список ключей массивом, иногда это пригождается.
    И кстати вредно писать для модели данных json структуру в которой массивом будет список объектов (значения свойств), а не массив однородных объектов, который можно было бы запихнуть сразу как модель, а не парсить еще один раз.
    Т.е. вместо:
    Код JSON:
    1. {
    2. "first":{начинка},
    3. "middle":{начинка},
    4. "last":{начинка},
    5. }
    Лучше написать:
    Код JSON:
    1. [
    2. {
    3. "name":"first",
    4. "data":{начинка}
    5. },
    6. {
    7. "name":"middle",
    8. "data":{начинка}
    9. },
    10. {
    11. "name":"last",
    12. "data":{начинка}
    13. }
    14. ]
    или так:
    Код JSON:
    1. {
    2. "branches":[
    3. {
    4. "name":"first",
    5. "data":{начинка}
    6. },
    7. {
    8. "name":"middle",
    9. "data":{начинка}
    10. },
    11. {
    12. "name":"last",
    13. "data":{начинка}
    14. }
    15. ]
    16. }
    тогда в чьей-то модели данных можно будет сразу написать так:
    model: JSON.parse(answer) или model: JSON.parse(answer).branches соответственно.
    Конечно если есть возможность самим придумать структуру.
  2. А если имена не нужны и всё есть в начинке, то это просто пихается в массив
    Код JSON:
    1. [
    2. {начинка},
    3. {начинка},
    4. {начинка}
    5. ]
    И тогда если воткнуть это куда-то в модель, то за данными можно будет уже обращаться без свойства data, т.е. modelData.свойство, вместо modelData.data.свойство
  3. Вот тут и вся проблема, что приходится работать с тем, что есть и структуру работы сервера не будут менять, ради того чтобы работало приложение.
  4. Вот так всегда((
    Тогда да, только самому собирать массив. Но я бы посадил это на биндинг, если возможно, тогда структура сама будет следить за изменениями данных, если сигналы шлются.
  5. Иногда приходится строить костыли со своей стороны, потому что с другой стороны ещё один костыль и им норм...АГРРРР
  6. Нагуглил. У jQuery есть функция each() которая как forEach, только как для массивов, так и для свойств работает. Оставив самое нужное получаем:
    Код QML:
    1. function each (obj, callback) {
    2. var value, i = 0;
    3. for (i in obj) {
    4. value = callback.call(obj[i], i, obj[i]);
    5. if (value === false) break;
    6. }
    7. return obj;
    8. }
    Ну и отсюда понятно как использовать, например:
    Код QML:
    1. var object = JSON.parse(answer)
    2. each(object, function(key,value){
    3. itemModel.append(value)
    4. }
    5. )
    Для одного раза может и нет смысла писать функцию, но в остальных случаях сгодится :)
  7. Это я к тому что даже в такой крупной библиотеке как jQuery ничего лучше не придумали как написать наподобие тому что сделали Вы))
  8. Осталось понять - либо я гений, как авторы jQuery, либо они мудаки как я? laugh
Copyright 2016-2024 NeoChapay