#angularjs #firebase #angularjs-ng-repeat #firebase-realtime-database
#angularjs #firebase #angularjs-ng-repeat #firebase-база данных в реальном времени
Вопрос:
Я получаю значения, сохраненные в поле «проекты» под данными текущего пользователя в базе данных Firebase под названием users:
первый метод:
var promise = MyUser.user();
promise.then( function onSuccess(user) {
$scope.userprojectskeys = user.projects;
});
второй способ:
var keyquery = DatabaseRef.ref('/users/' userId).orderByKey().once("value")
.then(function onSuccess(snapshot) {
snapshot.child("savedprojects").forEach(function(childSnapshot) {
var userprojects = childSnapshot.val();
console.log("my list is :", userprojects );
});
});
$scope.userprojectskeys
первого метода и userprojects
второго метода оба возвращают необходимые данные:
вывод первого метода:
my list is : -KUTLAZENGlxtzCtEfaZ
my list is : -KUTLM8r_kmVSTaxzLW5
my list is : -KUTPrs6ARZXjbjtNr7O
С другой стороны, у меня есть другая функция, которая получает список дочерних элементов в другой базе данных, называемой projects, например, следующим образом:
var projectquery = DatabaseRef.ref("projects").orderByKey().equalTo("-KUTPrs6ARZXjbjtNr7O");
$scope.projectslist = $firebaseArray(projectquery);
то, что я делаю сейчас, — это повторение полей объекта в $scope.projectslist
, отображение полей для каждого проекта.
<tr ng-repeat="obj in projectslist">
<td>{{ obj.field1}}</td>
<td>{{ obj.field2 }}</td>
<td>{{ obj.field3 }}</td>
<td>{{ obj.field4 }}</td>
</tr>
Вопрос :
как можно передать приведенный выше список ключей проекта, полученных ранее из данных текущего пользователя (либо с использованием первого, либо второго метода), в последнюю функцию, которая показывает проекты и фильтрует их по ключу в equalTo()
?
но, как вы можете видеть, я передаю один идентификатор проекта вручную в свой фильтр equalTo
, и он работает. Но мне нужно передать все ключи в equalTo.
одним из предлагаемых методов является:
один из предлагаемых методов заключается в объединении этих двух функций следующим образом:
$scope.projectslist = [];
DatabaseRef.ref('/users/' userId).orderByKey().once("value")
.then(function onSuccess(snapshot) {
snapshot.child("projects").forEach(function (childSnapshot) {
var userprojects = childSnapshot.val();
var projectquery = DatabaseRef.ref("projects").orderByKey().equalTo(userprojects);
$scope.projectslist.push($firebaseArray(projectquery));
});
});
но это безуспешно! в таблице отображаются строки, но внутри нет значения:http://imgur.com/uByHT3c
вот скриншот отладчика:http://i.imgur.com/TaDZLlk.png
Обновить:
вот структура моего users
дочернего элемента в mydatabase в firebase:
В котором вы можете видеть пять пользователей, и для каждого пользователя есть несколько полей, одно из которых является полем, в котором хранятся ключи пользовательских проектов, и в этом примере у пользователя есть четыре ключа проекта.
и вот дочерние проекты в firebase mydatabase:
здесь мы видим глобальное представление моей базы данных firebase. Итак, цель состоит в том, чтобы искать ключи проектов у пользователей, а затем показывать соответствующие проекты из базы данных проектов, то есть повторно повторять поля этих проектов.
Обновить:
вот журнал консоли после предложения Zura:
$scope.projectslist = [];
DatabaseRef.ref('/users/' userId).orderByKey().once("value")
.then(function onSuccess(snapshot) {
snapshot.child("projects").forEach(function (childSnapshot) {
var userprojects = childSnapshot.val();
//console.log("loaded. Data: ", userprojects);
var projectquery = DatabaseRef.ref("projects").orderByKey().equalTo(userprojects);
var list = ($firebaseArray(projectquery));
console.log("list: ", list);
});
});
каждый список содержит информацию, которая мне нужна для каждого проекта текущего пользователя. Идеально!
Но как получить к ним доступ и сохранить их в $scope
, чтобы иметь возможность вызывать это в моем html?
Обновить:
Я могу показать только последний проект, передав список в $scope:
показанный проект является последним в каждой итерации. Вопрос в том, как я могу показать все итерации forEach и передать его в массив?
обновление 25.10.2016:
вот обновленная версия кода, который объединяет объекты: сначала один, затем первые два вместе, первые три и, наконец, все объекты, объединенные в один большой массив, смотрите Журнал консоли ниже:
$scope.projectslist = [];
DatabaseRef.ref('/users/' userId).orderByKey().once("value")
.then(function onSuccess(snapshot) {
snapshot.child("projects").forEach(function (childSnapshot) {
var userprojects = childSnapshot.val();
var projectquery = DatabaseRef.ref("projects").orderByKey().equalTo(userprojects);
var list = $firebaseArray(projectquery);
$scope.list = $firebaseArray(projectquery);
console.log("list: ", $scope.list);
list.$loaded(function(){
$scope.projectslist = $scope.projectslist.concat(list);
console.log("loaded: ", $scope.projectslist);
});
});
});
и каждый объект напрямую содержит нужную мне информацию, как показано на предыдущем снимке экрана объекта.
Ответ №1:
Рекомендации
-
Когда это возможно, всегда используйте angularfire вместо оригинальных обещаний firebase. AngularFire автоматически выполняет 3-стороннюю привязку
$scope.$apply
. Так что вам не нужно думать об этом. -
Используйте
$firebaseObject
вместо$firebaseArray
, если вы извлекаете только один объект.
————————————————————————————————————————————
Ваша проблема в следующем коде.
$scope.projectslist.push($firebaseArray(projectquery));
firebaseArray()
возвращает массив, и что push
делает метод, так это то, что он помещает данный параметр в конец массива. Итак, здесь у вас будет массив, который также содержит массивы.
Вместо этого вы хотите объединить существующий массив с $firebaseArray(projectquery)
.
Я предлагаю попробовать следующий код.
var projectquery = DatabaseRef.ref("projects").orderByKey().equalTo(userprojects);
var list = $firebaseArray(projectquery);
list.$loaded(function(){
$scope.projectslist.contact(list);
});
И если вы используете angularfire, я думаю, вам следует изменить выборку пользовательских проектов, также используя $firebaseObject
. И вам не нужно использовать orderByKey
, потому что вы извлекаете только один объект.
var user = $firebaseObject(DatabaseRef.ref('/users/' userId));
user.$loaded(function(){
console.log("User loaded. Data: ", user);
angular.forEach(user.projects, function(value, key){
var projectquery = DatabaseRef.ref("projects").orderByKey().equalTo(key);
// var list = $firebaseArray(projectquery);
// list.$loaded(function(){
// $scope.projectslist = $scope.projectslist.concat(list);
// });
// or shortly. Replace 4 lines above with this line.
$scope.projectslist.push($firebaseObject(projectquery));
});
});
Обновить
Поскольку вы получаете только один список, было бы лучше попробовать $firebaseObject
получить объект и поместить его в массив.
ОБНОВЛЕНИЕ 25.10.2016:
Теперь ваша проблема здесь.
DatabaseRef.ref('/users/' userId).orderByKey().once("value")
.then(function onSuccess(snapshot) {
snapshot.child("projects").forEach(function (childSnapshot) {
Это сделано не в соответствии с моим предложением. Вы не используете angularfire, и html НЕ перекомпилируется автоматически. Вы должны вызывать $scope.$apply
в конце onSuccess
promise или лучше… Вы должны использовать подход angularfire, $firebaseObject
который автоматически вызывает $scope.$apply
.
var user = $firebaseObject(DatabaseRef.ref('/users/' userId));
user.$loaded(function(){
console.log("User loaded. Data: ", user);
angular.forEach(user.projects, function(value, key){
Комментарии:
1. Мой первый вопрос: Что такое контакт в вашей последней строке добавляется в список? откуда он взялся? что он делает? У меня его нет в исходном коде в вопросе. Во-вторых, я пытался реализовать ваш ответ, но безуспешно. И когда я реализую ваш второй код, я получаю предупреждение о дублирующемся объявлении для пользователя . Не могли бы вы, пожалуйста, пересмотреть свой ответ и дать мне знать, если у вас есть какие-либо предложения?
2. Я добавил запрошенные скриншоты структуры моей базы данных.
3. вы имеете в виду объединение с помощью контакта для объединения? в любом случае, я тоже пробовал это, но безуспешно.
4. Я заменил
$scope.projectslist.push($firebaseArray(projectquery));
вашим предложением:var list = $firebaseArray(projectquery);
в списке есть то, что мне нужно! но они хранятся в [0] каждого массива. Как их объединить? вот мой консольный журнал для списка , добавленного к вопросу..5. Да, это должно быть concat вместо contact. Извините за эту ошибку с опечаткой. И после конкатенации он возвращает новый массив вместо изменения существующего. Проверьте мой обновленный ответ.