javascript - 使用 Angular 在 firebase 中保存结构化数据

标签 javascript angularjs firebase firebase-realtime-database angularfire

我理解储蓄的概念和最佳实践 structured data在 firebase 中,但我不清楚如何将数据实际保存到多个位置并提供所需的交叉引用。

{
  articles: {
    -KBX5TurV9uJTeiR26-N: {
       title: 'post title 1',
       body: 'post body goes here',
       imagesRef: {
          -KBX5XOYASP7h2ZPOKmg: true
       }
    },
    -KCe7cy6QC29WRYap0D1: {
       title: 'post title 2',
       body: 'post body goes here',
       imagesRef: {
          -KBX5XOYASP7h2ZPOKmg: true
       }
    }
  }
  images: {
    -KBX5XOYASP7h2ZPOKmg: {
       image: 'data:image/gif;base64,R0lGODlhZABkAOYAAPj4...',
       articlesRef: {
          -KBX5TurV9uJTeiR26-N: true,
          -KCe7cy6QC29WRYap0D1: true
       }
    }
  }
}

上面的模式是我想要的一个例子。在提交由标题、正文和图像字段组成的表单时,我需要将标题和正文发布到文章对象,然后将图像发布到图像对象,然后使用交叉引用更新 imagesRef 和 articlesRef 对象。在 Angular 中解决这个问题的最佳方法是什么。我也有 angularfire 作为项目的一部分。

我是 angular 和 firebase 的新手,但我认为我需要发布两篇文章,一篇针对文章,一篇针对图像,以保存它们并生成唯一的 ID。然后我需要一些如何等待两者都成功,获取唯一的 ID 并在两个对象上执行和更新以保存交叉引用。到目前为止,这是我所拥有的,但不确定如何进一步......

     $scope.AddPost = function(){

        var ref = new Firebase(FIREBASE_URI);
        var newArticleRef = ref.child('articles').push();
        var newArticleKey = newArticleRef.key();

        // Create the data we want to update
        var addNewPost = {};
        addNewPost["articles/" + newArticleKey] = {
            title:   $scope.article.title,
            post:    $scope.article.post
        };

        if ($scope.image) {

            var newImageRef = ref.child('images').push();
            var newImageKey = newImageRef.key();

            // Add image...
            addNewPost['images/' + newImageKey] = {
                image: $scope.image
            };

            //Add article ref...
            addNewPost['images/' + newImageKey + '/articles/' + newArticleKey] = true;

            //Add cross ref to article...
            addNewPost['articles/' + newArticleKey + '/image/' + newImageKey] = true;

        }


        // Do a deep-path update
        ref.update(addNewPost, function(error) {
                if (error) {
                    console.log("Error:", error);
                }
        });

    });

更新:我更新了代码示例以使用 multi-location updatesfan-out approach ,但我在保存时遇到错误...

Error: Firebase.update failed: First argument contains a path /images/-KCpx-Pj9oMM-EWN9irS that is ancestor of another path /images/-KCpx-Pj9oMM-EWN9irS/articles/-KCpx-Pj9oMM-EWN9irR
at Error (native)
at ig (http://localhost:8000/app/assets/js/plugins.js:430:390)
at jg (http://localhost:8000/app/assets/js/plugins.js:431:383)
at X.update (http://localhost:8000/app/assets/js/plugins.js:564:369)
at r.$scope.AddPost (http://localhost:8000/app/assets/js/app.js:171:17)
at fn (eval at <anonymous> (http://localhost:8000/app/assets/js/plugins.js:216:110), <anonymous>:4:212)
at e (http://localhost:8000/app/assets/js/plugins.js:257:177)
at r.$eval (http://localhost:8000/app/assets/js/plugins.js:133:446)
at r.$apply (http://localhost:8000/app/assets/js/plugins.js:134:175)
at r.scopePrototype.$apply (chrome-extension://ighdmehidhipcmcojjgiloacoafjmpfk/dist/hint.js:1427:22)

警告:我尝试了以下方法。它创建了一个对象并且没有触发 JS 错误,但它清除了我的数据库,只留下了新创建的对象。没有损失太多,因为我现在只是在运行一些测试,但我认为我应该警告其他人。不要这样做...

        addNewPost.Articles = {};
        addNewPost.Articles[newArticleKey] = {};
        addNewPost.Articles[newArticleKey].title = $scope.article.title;
        addNewPost.Articles[newArticleKey].post = $scope.article.post;

        var newImageRef = ref.child('images').push();
        var newImageKey = newImageRef.key();

        addNewPost.images = {};
        addNewPost.images[newImageKey] = {};
        addNewPost.images[newImageKey].image = $scope.image;
        addNewPost.images[newImageKey].articles = {};
        addNewPost.images[newImageKey].articles[newArticleKey] = true;

        addNewPost.Articles[newArticleKey].image = {};
        addNewPost.Articles[newArticleKey].image[newImageKey] = true;

最佳答案

不确定这是最佳答案,但我发现以下答案对我有用。它利用 Frank van Puffelen 的建议来使用多位置更新。以下代码设置为支持添加新图像、使用现有图像或根本不使用图像。我认为这同样适用于类别、标签或用户中的任何元数据。

    .controller('AddPostController', ['$scope','$firebaseArray','FIREBASE_URI',
    function($scope,$firebaseArray,FIREBASE_URI) {

        var ref = new Firebase(FIREBASE_URI);

        $scope.AddPost = function(){

            var newArticleRef = ref.child('articles').push();
            var newArticleKey = newArticleRef.key();

            var newImageRef = ref.child('images').push();
            var newImageKey = newImageRef.key();

            // Create the data we want to update
            var addNewPost = {};

            // Add new article...
            addNewPost["articles/" + newArticleKey] = {
                title:   $scope.article.title,
                post:    $scope.article.post,
                emailId: user,
                '.priority': user
            };

            if ($scope.image) {

                // Add new image reference to new article...
                addNewPost["articles/" + newArticleKey].image = {};
                addNewPost["articles/" + newArticleKey].image[newImageKey] = true;

                // Add new image...
                addNewPost['images/' + newImageKey] = {
                    image: $scope.image,
                    emailId: user,
                    '.priority': user
                };

                // Add article reference to new image...
                addNewPost['images/' + newImageKey].articles = {};
                addNewPost['images/' + newImageKey].articles[newArticleKey] = true;

            } else if ($scope.article.image) {

                // Add existing image reference to article...
                addNewPost["articles/" + newArticleKey].image = {};
                addNewPost["articles/" + newArticleKey].image[$scope.article.image] = true;

                // Add new article reference to existing image...
                addNewPost['images/' + $scope.article.image + '/articles/' + newArticleKey] = true;

            }

            // Do a deep-path update
            ref.update(addNewPost, function(error) {
                if (error) {
                    console.log("Error:", error);
                }
            });

        };

    }]);

关于javascript - 使用 Angular 在 firebase 中保存结构化数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35964609/

相关文章:

javascript - 如何设置 react 表的响应高度

javascript - 如何在 AngularJS ng-if 语句中使用 ">"比较器

javascript - 没有子节点之一的 Firebase 数据检索

android - Firebase:处理请求时出现未知错误。再试一次。

android - 使用特定 ID 从 Firebase 检索数据

javascript - 如何在 php 查询中访问 javascript 变量?

javascript - Angular ng-repeat 创建表格问题

javascript - 如何将数组编码为包含函数的json?

javascript - 没有反射(reflect)我在 angularjs 中 `$rootScope` 的更改

javascript - 如何从另一个 Controller 中的指令访问范围