首页 文章

AngularJS Firebase数据库查询过滤器基于其他数据库

提问于
浏览
1

我将"projects"字段中存储的值存储在名为 users 的Firebase数据库中的当前用户数据下:

first method:

var promise = MyUser.user();
promise.then( function onSuccess(user) {
    $scope.userprojectskeys  = user.projects;
});

second method:

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 都返回所需的数据:

first method output:

enter image description here

second method output:

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() 中的键过滤它们?

但正如您所看到的,我手动将一个项目ID传递给我的过滤器 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

更新:

这是我在 mydatabase 中的 users 孩子在firebase中的结构:

enter image description here

在其中您可以看到五个用户,并且对于每个用户,有许多字段,其中一个是存储用户项目键的字段,在此示例中,用户有四个项目键 .

这里是firebase的项目子项 mydatabase

enter image description here

在这里,我们看到了我的firebase数据库的全局视图 . 因此,目标是从 users 查找项目键,然后显示项目数据库中的相应项目,即重复这些项目的字段 .

更新:

这是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中调用它?

enter image description here

更新:

我只能通过将列表传递给 $scope 来显示最后一个项目:
显示的项目是 forEach 迭代的最后一个 . The question is how can I show all of the iterations of forEach and pass it into an array?

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

        });
    });

enter image description here

每个对象直接包含我需要的信息,如上一个对象截图所示 .

1 回答

  • 2

    建议

    • 如有可能,请始终使用angularfire vs原始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 . 您应该在 onSuccess 承诺或更好的情况下调用 $scope.$apply ...您应该使用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){
    

相关问题