2015-01-15 6 views
1

Я новичок в Ember и JSON. Я хочу разобрать объект JSON, который находится ниже, с библиотекой типови получить доступ к значениям вложенных объектов, выполнив поиск их ключей.typeahead inested json object

У меня есть этот формат JSON:

return [ 
    { 
    "id": 1, 
    "category_name": "Supermarket", 
    "category_description": "SUPER MARKET", 
    "image_url": "", 
    "merchants": [ 
    { 
     "name": "CARREFOUR", 
     "id": 12, 
     "merchant_type_id": 1, 
     "merchant_type_description": "Gold", 
     "merchant_redeption_rate": 0.002500, 
     "image_url": "https://jpg", 
     "branches": [ 
     { 
     "id": 123456, 
     "latitude": 37.939483, 
     "area": "ΑΓ. ΔΗΜΗΤΡΙΟΣ", 
     "zip": "12345" 
     }, 
     { 
     "id": 4567890, 
     "longitude": 23.650622, 
     "area": "ΑΓ. ΙΩΑΝΝΗΣ ΡΕΝΤΗΣ", 
     "zip": "12345" 
     } 
     ] 
    }, 
    { 
     "name": "CAFCO", 
     "id": 13, 
     "merchant_type_id": 3, 
     "merchant_type_description": "None", 
     "merchant_redeption_rate": 0.002500, 
     "image_url": "https:.jpg", 
     "branches": [ 
     { 
     "id": 127890, 
     "latitude": 38.027870, 
     "area": "ΠΕΡΙΣΤΕΡΙ", 
     "zip": "12345" 
     } 
     ] 
    } 
    ] 
    }, 


{ 
    "id": 2, 
    "category_name": "Πολυκαταστήματα", 
    "category_description": "ΠΟΛΥΚΑΤΑΣΤΗΜΑ", 
    "image_url": "", 
    "merchants": [ 
    { 
    "name": "AGGELOPOYLOS CHR.", 
    "id": 15, 
    "merchant_type_id": 2, 
    "merchant_type_description": "Silver", 
    "merchant_redeption_rate": 0.002500, 
    "image_url": "https://www.nbg.gr/greek/retail/cards/reward-programmes/gonational/PublishingImages/aggelopoulos.jpg", 
    "branches": [ 
    { 
     "id": 234780, 
     "latitude": 35.366118, 
     "longitude": 24.479461, 
     "address": "ΕΘΝ. ΜΑΚΑΡΙΟΥ 9 & ΕΛ. ΒΕΝΙΖΕΛΟΥ 1", 
     "area": "Ν. ΦΑΛΗΡΟ", 
     "zip": "12345" 
    } 
    ] 
    } 
    ] 
} 


]; 

-------------------------- Изменен ---- ------------------------

Например, я хочу выполнить поиск с использованием typeahead имени торговцев и когда письмо, которое мы пишем, чтобы найти совпадения имя торговцев будет отображаться соответствующим category_name и назад.

Пример -> когда я клавиатура эля он появится: Категории: Супермаркет, Имени: CARREFOUR Имени: CAFCO

И тот же результат на выпадающем списке поиска, когда я клавиатура буква с.

Любая помощь?

New Jsbin example

ответ

0

Самый простой способ (на мой взгляд), чтобы получить эту работу, чтобы создать вычисляемое свойство, которое будет содержать массив широт. Но как мы туда доберемся?

Чтобы добраться до latitude, вам необходимо пройти через массив merchants, а затем массив branches. Будучи тем, что это будет через несколько элементов, вы собираетесь получить структуру данных типа «массив массивов», что раздражает. Таким образом, чтобы упростить это, мы можем создать простую flatten функции следующим образом:

flatten: function(origArray){ 
    var newArr = []; 
    origArray.forEach(function(el) { 
     el.forEach(function(eachEl){ 
     newArr.push(eachEl); 
     }); 
    }); 

    return newArr; 
    }, 

В дополнении к нашей функции выше, Эмбер уже дает нам много других полезных функций, которые могут быть использованы в массивах (см here). Один из них - mapBy(property), который преобразует массив в другой массив, только сохраняя значения указанного свойства.

Таким образом, чтобы создать (для широты) свойство lats, мы можем просто сделать это:

lats: function(){ 
    var merchantsArr = this.get('model').mapBy('merchants'); 
    merchantsArr = this.flatten(merchantsArr); 
    var branchesArr = merchantsArr.mapBy('branches'); 
    branchesArr = this.flatten(branchesArr); 

    return branchesArr.mapBy("latitude").compact(); 
}.property('model') 

Выше, я в основном с помощью mapBy, flatten (смотри выше) и compact которые

Возвращает копию массива со всеми удаленными и неопределенными элементами.

После того, как у вас есть имущество lats со всеми необходимыми данными, остальное легко.

Ваш призыв к компоненту становится:

{{x-typeahead data=lats name='category_name' selection=myColor}} 

Примечание lats вместо model вы изначально проходили в компонент.

И теперь, чтобы получить доступ к значению data собственности в компоненте, вы

`this.get('data')` 

, который вы можете просто передать в качестве source как так:

source: substringMatcher(self.get('data')) 

Рабочий раствор here

Обновление

Обновление моего ответа на основе вашего обновленного вопроса.

ОК, так что это становится немного сложнее. Теперь вам нужно больше, чем одно свойство (latitude). Вам нужны category_name и продавец name.

В дополнение к mapBy, который просто захватывает одно свойство из массива, Ember также map, который позволяет преобразовать массив в значительной степени все, что вы хотите:

lats: function(){ 
    var merchantsArr = this.get('model').map(function(thing){ 
    var category_name = thing.category_name; 
    return thing.merchants.map(function(merchant){ 
     return { 
     "name": merchant.name, 
     "category": category_name 
     }; 
    }); 
    }); 

    merchantsArr = this.flatten(merchantsArr); 

    return merchantsArr; 
}.property('model') 

код выше выглядит сложным, но это в основном просто возврат массива торговцев объектов верхнего уровня, сопровождаемый category_name. Поскольку это массив массивов, нам нужно будет сгладить его.

Тогда внутри компонента нам нужно иметь в виду, что мы не просто передаем массив строк, а скорее передаем массив объектов. Таким образом, мы должны смотреть через свойства объекта (название и категория) на матч

$.each(strs, function(i, str) { 
    if (substrRegex.test(str.name) || substrRegex.test(str.category)) { 
    matches.push(str); 
    } 
}); 

Наконец, на самом деле отображать как категорию и имя торговца, вам нужно сказать машинописный, как это сделать:

templates: { 
    suggestion: Handlebars.compile('<p>{{name}} – {{category}}</p>') 
} 

Рабочее решение here

+0

Большое спасибо за ваш ответ! Ты обалденный! Я редактирую свой вопрос с новыми данными и новыми функциями поиска. Если у вас есть время взглянуть. – thodwris

+0

Я обновил свой ответ, чтобы ответить на ваше обновление – Kalman