2016-04-29 6 views
11

Я хочу получить список элементов в firebase, но каждый элемент элемента имеет список связанных элементов. Я не смог получить список, не используя firebase-util, а также функцию firebase array $extend.Получить список связанных элементов списка элементов в массиве firebase

Мой firebase данных выглядит следующим образом:

items 
    item1 
     name: "Item 1" 
     user: user1 
     images 
      image1: true 
      image2: true 
    item2 
     name: "Item 2" 
     user: user1 
     images: 
      image3: true 
      image4: true 
    item3 
     name: "Item 3" 
     user: user2 
     images: 
      image5: true 
      image6: true 

users 
    user1 
     name: "User 1" 
     email: "[email protected]" 
    user2 
     name: "User 2" 
     email: "[email protected]" 

images 
    image1 
     image: "data:image/jpeg;base64,/9j/..." 
     thumb: "data:image/jpeg;base64,/9j/..." 
    image2 
     image: "data:image/jpeg;base64,/9j/..." 
     thumb: "data:image/jpeg;base64,/9j/..." 
    image3 
     image: "data:image/jpeg;base64,/9j/..." 
     thumb: "data:image/jpeg;base64,/9j/..." 
    image4 
     image: "data:image/jpeg;base64,/9j/..." 
     thumb: "data:image/jpeg;base64,/9j/..." 
    image5 
     image: "data:image/jpeg;base64,/9j/..." 
     thumb: "data:image/jpeg;base64,/9j/..." 

И я просто хочу, чтобы получить список элементов со всеми данными. Что-то вроде:

items 
    item1 
     name: "Item 1" 
     user 
      name: "User 1" 
      email: "[email protected]" 
     images 
      image1 
       image: "data:image/jpeg;base64,/9j/..." 
       thumb: "data:image/jpeg;base64,/9j/..." 
      image2 
       image: "data:image/jpeg;base64,/9j/..." 
       thumb: "data:image/jpeg;base64,/9j/..." 
    item2 
     name: "Item 2" 
     user 
      name: "User 1" 
      email: "[email protected]" 
     images 
      image3 
       image: "data:image/jpeg;base64,/9j/..." 
       thumb: "data:image/jpeg;base64,/9j/..." 
      image4 
       image: "data:image/jpeg;base64,/9j/..." 
       thumb: "data:image/jpeg;base64,/9j/..." 
    item3 
     name: "Item 3" 
     user 
      name: "User 2" 
      email: "[email protected]" 
     images 
      image5 
       image: "data:image/jpeg;base64,/9j/..." 
       thumb: "data:image/jpeg;base64,/9j/..." 
      image6 
       image: "data:image/jpeg;base64,/9j/..." 
       thumb: "data:image/jpeg;base64,/9j/..." 

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

+0

Как это, вы не можете получить данные в формате, который вы просите на основе вашего текущая структура. Можете ли вы предоставить информацию о том, почему вы хотите получить ВСЕ эти данные за один раз? Как правило, вы получите список имен пользователей или список изображений, которые идут с пунктом 3, но обычно не все одновременно. Я думаю, что может быть решение вашего вопроса, и понимание варианта использования поможет. – Jay

+0

@Jay Я хочу показать список предметов. Каждый элемент имеет список изображений, но я просто покажу один из них в списке как основное изображение предмета. И почему бы и нет, возможно, на мышином я хотел бы перейти на другой. Но, по крайней мере, если бы я мог сделать это только с одним, было бы хорошо. – cor

ответ

2

Благодаря @Jay и @Eric за ответы, они очень полезны, мое решение имеет немного обоих. Я объясню, как я это понял.

Во-первых, я изменил схему и добавил новый ключ для основного изображения элемента. Я назвал его cover. Но, отвечая на исходный вопрос, я сделаю это, загрузив все изображения. Так вот новая items схема:

items 
    item1 
     name: "Item 1" 
     user: user1 
     cover: image1 
     images 
      image1: true 
      image2: true 
    item2 
     name: "Item 2" 
     user: user1 
     cover: image3 
     images: 
      image3: true 
      image4: true 
    item3 
     name: "Item 3" 
     user: user2 
     cover: image5 
     images: 
      image5: true 
      image6: true 

Тогда это то, как я получаю список упомянутых выше (с использованием async библиотеки). Это может быть лучший подход для достижения той же:

getItems: function(cb){ 
    var items = ref.child("items"); 
    items.on("value", function(snapshot){ 

     var item_length = snapshot.numChildren(), 
      final_items = [], 
      readed = 0; 

     ref.child("items").on("child_added", function(item){ 

      var item_id = item.key(), 
       itemData = item.val(), 

       user = ref.child("users").child(itemData.user), 
       cover = ref.child("images").child(itemData.cover), 
       images = new Firebase.util.NormalizedCollection(
         [ref.child("items").child(item_id).child("images"),'alertImages'], 
         ref.child('images') 
       ).select('images.image','images.thumb').ref(); 

       async.parallel([ 
        function(callback){ 
         user.on("value", function(user_snap){ 
          callback(null, user_snap.val()); 
         }); 
        }, 
        function(callback){ 
         images.on("value", function(images_snap){ 
          callback(null, images_snap.val()); 
         }); 
        }, 
        function(callback){ 
         cover.on("value", function(cover_snap){ 
          callback(null, cover_snap.val()); 
         }); 
        } 
       ], function(err, results){ 
        if(!!err){ 
         cb(err,null) 
        }else{ 
         itemData.user = results[0]; 
         itemData.images = results[1]; 
         itemData.cover = results[2]; 

         final_items.push(itemData); 
         readed += 1; 
         if(readed === item_length){ 
          cb(null,final_items); 
         } 
        } 
       }); 
     }); 
    }); 
} 

И это будет что-то вроде:

item1 
    name: "Item 1" 
    cover: 
     image: "data:image/jpeg;base64,/9j/..." 
     thumb: "data:image/jpeg;base64,/9j/..." 
    user 
     name: "User 1" 
     email: "[email protected]" 
    images 
     image1 
      image: "data:image/jpeg;base64,/9j/..." 
      thumb: "data:image/jpeg;base64,/9j/..." 
     image2 
      image: "data:image/jpeg;base64,/9j/..." 
      thumb: "data:image/jpeg;base64,/9j/..." 
item2 
    name: "Item 2" 
    cover: 
     image: "data:image/jpeg;base64,/9j/..." 
     thumb: "data:image/jpeg;base64,/9j/..." 
    user 
     name: "User 1" 
     email: "[email protected]" 
    images 
     image3 
      image: "data:image/jpeg;base64,/9j/..." 
      thumb: "data:image/jpeg;base64,/9j/..." 
     image4 
      image: "data:image/jpeg;base64,/9j/..." 
      thumb: "data:image/jpeg;base64,/9j/..." 
item3 
    name: "Item 3" 
    cover: 
     image: "data:image/jpeg;base64,/9j/..." 
     thumb: "data:image/jpeg;base64,/9j/..." 
    user 
     name: "User 2" 
     email: "[email protected]" 
    images 
     image5 
      image: "data:image/jpeg;base64,/9j/..." 
      thumb: "data:image/jpeg;base64,/9j/..." 
     image6 
      image: "data:image/jpeg;base64,/9j/..." 
      thumb: "data:image/jpeg;base64,/9j/..." 
+0

Рад, что у вас есть решение. Следите за этими асинхронными вызовами внутри других асинхронных вызовов. Это может вызвать у вас неприятности, поэтому я часто проверяю ваши данные - особенно с помощью push() и тестирования на нескольких устройствах, которые читают/записывают данные примерно в одно и то же время. – Jay

+0

Спасибо за совет @Jay, я искал такой код в ответах, а не только о структуре кода. На данный момент я не нашел ничего лучшего. Я буду продолжать пытаться, хотя – cor

4

Цель состоит в том, чтобы показать список предметов.

В каждом элементе есть список изображений.

Первоначально покажите список товаров и одно из изображений для каждого элемента.

Предлагаемый подход:

Для заполнения списка элементов и их начальных эскизов, мы должны иметь отдельный узел, который мы тянем начальную установку с.

Обновленные элементы узла

items: 
    item_id_xx: //this should be a Firebase generated node name 
    name: "Item 2" 
    user: "uid_for_user_1" 
    images: 
    image3: "data:image/jpeg;base64,/9j/..." 
    image4: "data:image/jpeg;base64,/9j/..." 

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

item_list_for_ui 
    random_node_0 
    item_id: "item_id_aa" 
    name: "Item 1" //if you want to display the name in the list 
    initial_thumb: "data:image/jpeg;base64,/9j/..." //initial thumb 
    link_to: "image1" 
    random_node_1 
    item_id: "item_id_xx" 
    name: "Item 2" 
    initial_thumb: "data:image/jpeg;base64,/9j/..." 
    link_to: "image3" 
    random_node_2 
    item_id: "item_id_qq" 
    name: "Item 3" 
    initial_thumb: "data:image/jpeg;base64,/9j/..." 
    link_to: "image1" 

При запуске приложения, наполнитьсетевую список из узла items_list_for_ui.

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

Например: Если пользователь нажимает на миниатюру для пункта 2, деталь пункта может быть загружена с observeSingleEvent .value в

/деталь/item_id_xx/изображения/image3

Вы могли бы изложить на этом добавив скажем, ссылку на опрокидывание в item_list_for_ui

random_node_1 
    item_id: "item_id_xx" 
    name: "Item 2" 
    initial_thumb: "data:image/jpeg;base64,/9j/..." 
    thumb_link: "image3" 
    rollover_thumb: "external link to rollover" 
    rollover_link: "image4" 

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

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

С этой структурой item_list_for_ui компактен, поэтому даже с сотнями элементов это небольшое подмножество этих данных.

Возможно, вы говорите себе, это дубликаты данных.Да, это так, и дублирование данных в Firebase является нормальным процессом и поощряется: он сохраняет структуру более плоской и делает запросы и работу с данными намного быстрее.

Для получения дополнительного чтения см Denormalizing Data Keeps Your Breath Minty Fresh

+0

Спасибо за ответ @Jay. Но как вы присоединитесь к данным? вы бы использовали плагин «firebase-util»? Если да, то как? Я не знаю, как это сделать, поскольку идентификатор элемента является динамическим. – cor

+0

@cor Firebase не имеет функции объединения, поскольку это не SQL. Существует несколько способов связать данные и дублировать данные в Firebase. Я думаю, что мой ответ ответил на ваш прямой вопрос. Ваш комментарий/продолжение - это отличный новый вопрос (и есть некоторые ответы, которые касаются его уже на Stackoverflow). Проверьте эти ответы, и если у вас есть конкретный вопрос, опубликуйте его! – Jay

+0

извините, вы правы – cor

2

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

var itemsArr = []; 
    for(var i in items) { 
     var item = items[i]; 
     var images = []; 
     for(var image in item[images]) { 
      item.push(images[image]); 
     } 
     itemsArr.push({ 
      name: item.name, 
      user: users[item.user], 
      images: images 
     }); 
    } 

Который должен дать массив объектов вида:

{ 
    name: "Item 1", 
    user: { 
     name: "User 1", 
     email: "[email protected]" 
    }, 
    images: [{ 
      image: "data:image/jpeg;base64,/9j/..." 
      thumb: "data:image/jpeg;base64,/9j/..." 
     },{ 
      image: "data:image/jpeg;base64,/9j/..." 
      thumb: "data:image/jpeg;base64,/9j/..." 
    }] 
} 
+0

Большое спасибо @Eric N, ваш ответ был полезен для того, что я хотел достичь – cor

 Смежные вопросы

  • Нет связанных вопросов^_^