Вы можете попытаться использовать гиперссылку в качестве родителя, а затем изменить внутренние элементы при наведении. Например:
a.active h1 {color:red;}
a.active:hover h1 {color:green;}
a.active h2 {color:blue;}
a.active:hover h1 {color:yellow;}
Таким образом вы можете изменить стиль во множестве внутренних тегов на основе опрокидывания родительского элемента.
Ваша текущая структура данных отлично подходит для поиска участников определенного чата. Это не очень хорошая структура для поиска обратного: чаты, в которых участвует пользователь.
Несколько проблем здесь:
Чат может иметь несколько участников, поэтому вы смоделировали это как массив. Но на самом деле это не идеальная структура данных. Вероятно, каждый участник может быть только в чате один раз. Но, используя массив, я мог бы:
participants: ["puf", "puf"]
Это явно не то, что вы имеете в виду, но структура данных позволяет это. Вы можете попытаться обеспечить это в коде и правилах безопасности, но было бы проще, если бы вы начали с структуры данных, которая неявно соответствует вашей модели.
Мое эмпирическое правило: если вы обнаружите, что пишете array.contains()
, вы должны использовать набор.
Набор представляет собой структуру, в которой каждый ребенок может присутствовать не более одного раза, поэтому он естественным образом защищает от дубликатов. В Firebase вы моделируете набор как:
participants: {
"puf": true
}
Здесь true
здесь действительно просто фиктивное значение: важно то, что мы переместили имя на ключ. Теперь, если я попытаюсь снова присоединиться к чату, это будет noop:
participants: {
"puf": true
}
И когда вы присоединитесь:
participants: {
"john": true,
"puf": true
}
Это самый прямой представление вашего требования: коллекция, которая может содержать только каждого участника один раз.
. С указанной структурой вы могли запросить для чатов, в которых вы находитесь:
ref.child("chats").orderByChild("participants/john").equalTo(true)
Проблема заключается в том, что для этого требуется, чтобы вы определяли индекс для `members / john ':
{
"rules": {
"chats": {
"$chatid": {
"participants": {
".indexOn": ["john", "puf"]
}
}
}
}
}
Это будет работать и но теперь каждый раз, когда кто-то новый присоединяется к чат-приложению, вам нужно добавить еще один индекс. Это явно не масштабируемая модель. Нам нужно будет изменить нашу структуру данных, чтобы разрешить требуемый запрос.
Второе правило: моделируйте ваши данные, чтобы отразить то, что вы показываете в своем приложении.
Поскольку вы ищете показать список чатов для пользователя, сохранить чаты для каждого пользователя:
userChatrooms: {
john: {
chatRoom1: true,
chatRoom2: true
},
puf: {
chatRoom1: true,
chatRoom3: true
}
}
Теперь вы можете si просто определите свой список чатов с помощью:
ref.child("userChatrooms").child("john")
И затем перейдите по клавишам, чтобы получить каждую комнату.
Вам понравится иметь два соответствующих списка в вашем приложении:
Кроме того, в базе данных есть оба списка.
chatroomUsers
chatroom1
user1: true
user2: true
chatroom2
user1: true
user3: true
userChatrooms
user1:
chatroom1: true
chatroom2: true
user2:
chatroom1: true
user2:
chatroom2: true
Я вытащил оба списка на верхний уровень дерева, так как Firebase рекомендует против вложенных данных.
Наличие обоих списков совершенно нормально в решениях NoSQL. В приведенном выше примере мы будем ссылаться на userChatrooms
как инвертированный индекс chatroomsUsers
.
.childChanged
за чаты, членом которых я являюсь. Если я попытаюсь настроить наблюдателя для чатов, гдеmembers/myId = true
, то я получаю неуказанную ошибку индекса. Как бы вы это сделали? У меня есть вопрос, размещенный здесь: stackoverflow.com/questions/47769044/… – lusus_vir 17 December 2017 в 00:14