2016-04-29 19 views
11

Tôi muốn nhận danh sách các mục trong cơ sở firebase, nhưng mỗi phần tử của mục có danh sách các mục có liên quan. Tôi đã không thể có được danh sách, không sử dụng chức năng firebase-util cũng như mảng firebase $extend.Truy xuất danh sách mục có liên quan của danh sách mục trong mảng firebase

dữ liệu căn cứ hỏa lực của tôi trông giống như sau:

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/..." 

Và tôi chỉ muốn có được một danh sách các mục với tất cả các dữ liệu. Một cái gì đó như:

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/..." 

Dường như trường hợp sử dụng khá phổ biến, nhưng tôi bị kẹt ở đây. Tôi đã thử giải pháp this (theo cả hai cách) nhưng tôi không thể làm cho nó hoạt động. Cấu trúc dữ liệu cũng hơi khác một chút vì tôi cần liên kết một danh sách nằm trong danh sách khác.

+0

Vì nó là, bạn không thể lấy dữ liệu theo định dạng bạn đang yêu cầu dựa trên của bạn cấu trúc hiện tại. Bạn có thể cung cấp thông tin về lý do bạn muốn nhận TẤT CẢ dữ liệu đó cùng một lúc không? Thông thường, bạn sẽ nhận được danh sách tên người dùng hoặc danh sách hình ảnh đi kèm với Mục 3 nhưng thường không phải tất cả cùng một lúc. Tôi nghĩ rằng có thể có một giải pháp cho câu hỏi của bạn và hiểu được trường hợp sử dụng sẽ giúp ích. – Jay

+0

@Jay Tôi muốn hiển thị danh sách mục. Mỗi mục có một danh sách các hình ảnh, nhưng tôi sẽ chỉ hiển thị một trong số chúng trong danh sách dưới dạng ảnh chính của mục. Và tại sao không, có lẽ khi di chuột qua tôi muốn đổi sang một cái khác. Nhưng ít nhất nếu tôi có thể làm điều đó chỉ với một nó sẽ được tốt đẹp. – cor

Trả lời

2

Nhờ @ Jay và @ Eric cho câu trả lời, họ đã rất hữu ích, giải pháp của tôi có một chút của cả hai. Tôi sẽ giải thích làm thế nào tôi đã tìm ra nó.

Thứ nhất, tôi đã thay đổi giản đồ và thêm khóa mới cho ảnh chính của mục. Tôi đã gọi nó là cover. Nhưng trả lời câu hỏi ban đầu, tôi sẽ làm nó tải tất cả các hình ảnh. Vì vậy, đây là mới items schema:

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 

Sau đó, đây là cách tôi có được danh sách nêu trên (sử dụng async thư viện). Nó có thể là một phương pháp tốt hơn để thực hiện giống nhau:

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); 
         } 
        } 
       }); 
     }); 
    }); 
} 

và điều này sẽ ra một cái gì đó như:

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

Vui vì bạn có một giải pháp. Theo dõi các cuộc gọi không đồng bộ đó bên trong các cuộc gọi không đồng bộ khác. Điều đó có thể khiến bạn gặp rắc rối vì vậy tôi sẽ kiểm tra dữ liệu của bạn thường xuyên - đặc biệt với push() và kiểm tra trên một số thiết bị đọc/ghi dữ liệu cùng một lúc. – Jay

+0

Cảm ơn lời khuyên @Jay, tôi đã tìm kiếm một số mã như vậy trong các câu trả lời, không chỉ về cấu trúc mã. Tại thời điểm này tôi đã không tìm thấy bất cứ điều gì tốt hơn. Tôi sẽ tiếp tục cố gắng – cor

4

Mục tiêu là hiển thị danh sách mục.

Mỗi mục có danh sách hình ảnh.

Ban đầu, hiển thị danh sách mục và một trong các hình ảnh cho mỗi mục.

cách tiếp cận Đề xuất:

Để đưa vào danh sách các mặt hàng và hình thu nhỏ ban đầu của họ, chúng ta cần phải có một nút riêng biệt mà chúng tôi kéo thiết lập ban đầu từ đâu.

mục Cập nhật nút

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/..." 

Dưới đây là nút dùng để xem danh sách chính, nơi người dùng có thể nhấp chuột vào một ngón tay cái mục để có được chi tiết hơn:

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" 

Khi ứng dụng bắt đầu, cư danh sách từ nút items_list_for_ui.

Nút này cạn và chứa mục Firebase item_id, tên mục (nếu cần), liên kết để nhận hình thu nhỏ hình ảnh ban đầu và liên kết_to của hình ảnh chính trong Firebase.

Ví dụ: Nếu người dùng nhấp vào hình thu nhỏ cho khoản 2, các chi tiết mặt hàng có thể được nạp bởi observeSingleEvent với .Value tại

/mục/item_id_xx/images/image3

Bạn có thể trình bày chi tiết về vấn đề này bằng cách thêm tiếng nói, một liên kết tái đầu tư vào 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" 

cấu trúc này là rất linh hoạt trong đó bạn có thể thay đổi ra những ngón tay cái và hiệu ứng rollover bạn muốn hiển thị trong danh sách chính bằng cách chỉ cập nhật những nút con tương ứng.

Nó cũng hiệu quả vì nó tránh tải hàng trăm mục và hàng trăm nút ảnh con - tải tất cả các nút đó và nút con sẽ làm quá tải ui (trong một số trường hợp).

Với cấu trúc này, item_list_for_ui nhỏ gọn nên ngay cả với hàng trăm mục, nó là một tập con nhỏ của dữ liệu đó.

Có thể bạn đang tự nói với chính mình 'bản thân, đó là dữ liệu trùng lặp'.Có, nó là, và nhân đôi dữ liệu trong Firebase là một quá trình bình thường và khuyến khích: nó giữ cấu trúc phẳng hơn và làm cho các truy vấn và làm việc với dữ liệu nhanh hơn nhiều.

Để đọc nhiều thấy Denormalizing Data Keeps Your Breath Minty Fresh

+0

Cảm ơn câu trả lời @Jay. Nhưng làm thế nào bạn sẽ tham gia dữ liệu? bạn có sử dụng plugin 'firebase-util' không? Nếu vậy, làm thế nào? Tôi không biết cách thực hiện mối quan hệ vì id mục là động – cor

+0

@cor Firebase không có hàm tham gia vì nó không phải là SQL. Có một số cách để liên kết dữ liệu và sao chép dữ liệu là không thể thực hiện trong Firebase. Tôi nghĩ câu trả lời của tôi đã trả lời câu hỏi trực tiếp của bạn. Nhận xét của bạn/theo dõi là một câu hỏi mới tuyệt vời (và có một số câu trả lời giải quyết nó đã có trên Stackoverflow). Hãy xem những câu trả lời đó và nếu bạn có câu hỏi cụ thể, hãy đăng câu hỏi đó! – Jay

+0

xin lỗi, bạn đang đúng – cor

2

Nếu bạn có tất cả những gì có sẵn dữ liệu bạn có thể lặp qua hình ảnh của bạn và sử dụng siêu dữ liệu của nó như là chìa khóa trong phần còn lại của cơ sở dữ liệu.

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 
     }); 
    } 

nào nên mang một mảng của các đối tượng tìm kiếm như thế này:

{ 
    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

Rất cám ơn @Eric N, câu trả lời của bạn là hữu ích cho những gì tôi muốn đạt được – cor

Các vấn đề liên quan