【问题标题】:is this just a bad use-case for AngularFire?这只是 AngularFire 的一个糟糕的用例吗?
【发布时间】:2014-09-06 01:19:57
【问题描述】:

我已经玩了 AngularFire 几天了,我想知道我是否可能只是在尝试最终对它不利的用例。我将在我的网站上进行实时聊天/呈现,所以这部分很有用。不过,我正在处理这件作品 - 我不知道。

所以我有一个注册表单。当用户注册时,他们必须从下拉列表中选择一种颜色。我将列表存储在 Firebase 的一个数组中。

我正在尝试维护一个相当严格的 MVC 设置,因此我将每个控制器以及每个相应的服务都放在自己的文件中。我之前编写的 Angular 应用程序使用了这种结构,并且一直运行良好,直到现在。

我想不通的是简单地读回列表并将其填充到下拉列表中的正确方法。

在以前的 Angular 应用程序中,它只是直截了当:

return $resource(URL + /colors);

所以在 AngularFire 中,我基本上使用的是这个,它正在工作,buuuuutttt:

getColors: function($scope) {
            syncData('usergen/colors').$bind($scope, 'colorsRaw').then(function() {
                var keys = $scope.colorsRaw.$getIndex();
                angular.forEach(keys, function(key) {
                    var color = {label: $scope.colorsRaw[key], value: $scope.colorsRaw[key]};
                    $scope.data.colors.push(color);
                });
                $scope.data.color = $scope.data.colors[Math.floor(Math.random() * $scope.data.colors.length)];
            });
        }

当然,现在我绝对讨厌它:为什么我必须像这样传递 $scope?我似乎不能只让 getColor() 返回 {name: "Blue", value: "Blue"} 对象的常规数组。我不仅必须传递 $scope,而且我不能将下拉列表设置为随机值,除非我在服务中这样做。坏坏坏。我根本不想将 Ctrl $scope 传递到服务中,当然也不想从服务中更新 Ctrl $scope 变量。

那么我到底错过了什么? Firebase 似乎相当发达,所以我敢肯定这是我完全缺乏理解。我完成了所有的聊天示例、教程和其他事情,但没有什么能像我在这里尝试做的那样。

那么有没有办法为 Firebase/AngularFire 调用提供单独的服务,让我只需将值返回到我的控制器,而无需传入 $scope var?

谢谢。

【问题讨论】:

    标签: javascript angularjs angularjs-scope firebase angularfire


    【解决方案1】:

    当然现在我绝对讨厌它:为什么我必须像这样传递 $scope?

    很多人认为您必须在 AngularFire 中使用 $scope你不仅可以在没有$scope 的情况下使用它,而且在大多数情况下都建议使用它

    $scope 中过多地使用 AngularFire 也会降低您的应用程序的速度,因为 Angular 现在的任务是跟踪它。

    在使用 AngularFire 时,我通常在工厂/服务级别创建我的 $firebase 绑定。通过这种方式,它变得可重复使用且易于维护。然后我可以在控制器的 $scope 上创建简单的数组,并在添加新项目时推送。

    Plunker Demo

    angular.module('app', ['firebase'])
    
    .constant('FBURL', 'https://<your-firebase>.firebaseio.com/')
    
    .service('FbRef', ['FBURL', Firebase])
    
    .factory('Colors', function (FbRef, $firebase, $q) {
        var $colors = $firebase(FbRef.child('colors'));
        return {
            get: function getColors() {
                var deferred = $q.defer();
    
                $colors.$on('loaded', function (colors) {
    
                    var colorArr = [];
                    angular.forEach(colors, function (color) {
                        colorArr.push(color);
                    });
    
                    deferred.resolve(colorArr);
                });
    
                return deferred.promise;
            },
            add: function addColor(color) {
                $colors.$add(color);
            }
        };
    })
    
    .controller('RegisterCtrl', function ($scope, Colors) {
    
        $scope.colors = [];
    
        // listen for added colors
        // this will grab all of the colors on load
        Colors.get().then(function (colors) {
            $scope.colors = colors;
            var randomIndex = getRandomIndex(0, colors.length - 1);
            $scope.current = colors[randomIndex];
        });
    
        function getRandomIndex(min, max) {
            return Math.floor(Math.random() * max) + min;
        }
    
    });
    

    视图只是使用ng-modelng-options 进行的简单选择。

    <select ng-model="current" ng-options="c for c in colors"></select>
    

    【讨论】:

    • 这很棒。绝对解决了我的 $scope 问题。但是,我仍然不清楚随机分配一个值。我了解 promises 和 .defer() 的工作原理,但我不明白为什么它在这种情况下不起作用。因此,在我加载完所有颜色后,我需要将 .current 随机设置为一个值,例如 $scope.current = $scope.colors[ Math.floor(Math.random() * $scope.colors.length)) ]; 但当然,由于颜色是异步加载的 - 大多数情况下调用都会失败。
    • 将此答案标记为一个。我意识到我可以在 Colors.listen 函数中分配一个随机值。冗余,因为每次我添加新颜色时都会这样做?是的。但它有效,而且现在已经足够了。
    • 我实际上刚刚更新了我的答案,以满足您对随机颜色的需求。我们可以一次性抓住它们并在承诺中归还它们,而不是倾听颜色。一旦该承诺被初始化,我们将颜色设置为 $scope 并获取一个随机索引。
    猜你喜欢
    • 2011-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-07
    • 1970-01-01
    • 1970-01-01
    • 2012-09-06
    • 2011-08-01
    相关资源
    最近更新 更多