Структура данных
При построении с помощью Firebase ключевым моментом является денормализация ваших данных. В вашем сценарии я бы предложил сохранить вторичный индекс, который содержал бы только имена ваших животных с уникальным ключом для загрузки деталей. Например:
{
"names":
{
"Dog": 0,
"Cat": 1,
"Cow": 2
},
"animals":
{
0: {name:"Dog", details:{somestuffhere}},
1: {name:"Cat", details:{somestuffhere}},
2: {name:"Cow", details:{somestuffhere}}
}
}
Теперь вы можете использовать обычную ссылку Firebase для загрузки всех дочерних элементов /names
, а затем решить, какие детали вы хотите загрузить.
Когда вы добавляете новое животное, не забудьте также добавить соответствующую запись /names
.
Использование этой структуры с AngularJS
Вы правы в том, что AngularFire загрузит все данные заданного пути, однако мы можем ограничить это, используя нашу новую структуру данных. Вместо использования одного общего AngularFire, который загружает все наши данные, мы можем использовать несколько AngularFire и быть более избирательными.
Этот первый AngularFire загружает наш список имен.
// Load the list of names to $scope.names
angularFire(new Firebase("http://[Your Firebase].firebaseio.com/names"), $scope, "names"));
Затем, когда пользователь выбирает животное, используется новый AngularFire для пути /names/{Animal}
для динамической загрузки сведений об этом животном. В этом примере предполагается, что уникальный ключ животного хранится в переменной animalKey
.
// Load the specific animal details to $scope.animal
angularFire(new Firebase("http://[Your Firebase].firebaseio.com/animals/").child(animalKey), $scope, "animal"));
Теперь данные о нашем животном выставлены на $scope.animal
, и мы не загрузили все ненужные данные о других животных.
Безопасное добавление новых животных
Ответ на комментарий к этому ответу
Общий совет: никогда не используйте увеличивающиеся целые числа в качестве ключей в Firebase. Из-за того, что Firebase работает в режиме реального времени, вероятность того, что два пользователя одновременно добавят новый элемент с одним и тем же увеличенным целочисленным ключом (в данном случае 3
), очень высока, что приведет к перезаписи одной из их записей. . Вместо этого используйте .push()
Firebase.
В вашем сценарии вы должны обойти AngularFire и использовать .push
в ссылке Firebase. Попробуй это:
var newAnimalRef = (new Firebase('http://[Your Firebase].firebaseio.com'))
.child('animals')
.push({name: 'Fish', details: ""});
Он создаст новый дочерний элемент /animals
с таким ключом, как -fj213jjkaisdja
. Затем мы можем использовать .once
, чтобы добавить новый элемент в индекс /names
:
newAnimalRef.once('value', function (snapshot) {
(new Firebase('http://[Your Firebase].firebaseio.com'))
.child('names')
.child(snapshot.val().name)
.set(snapshot.name())
});
Затем бум, мы добавили ребенка чистым и безопасным способом.
Заключительные примечания
Вот ссылка на официальный пост в блоге о денормализации данных, и в целом это хороший ресурс, если вы работаете с реляционными базами данных.
Будьте осторожны при потенциальном создании нескольких AngularFires, связанных с одним и тем же полем в $scope
. Если вы не будете осторожны, вы можете закончить тем, что изменения в одном поле будут записаны в несколько путей в Firebase. Чтобы предотвратить это, либо привяжите AngularFire только к $scope
, который будет регулярно отключаться (т. е. к контроллеру, специфичному для модуля, отображающего данные о животных), либо используйте метод disassociate, переданный в разрешенное обещание из AngularFire, как я делаю в другой мой ответ.
person
Abe Haskins
schedule
10.12.2013
Dog/Cat/Cow
иsomestuffhere
и превратить это в совет о том, как структурировать доставку 5 МБ данных для приложения, о котором они ничего не знают. - person charlietfl   schedule 10.12.2013