如何在不保存的情况下更新多个firebase引用?

时间:2014-07-18 04:01:09

标签: javascript angularjs firebase angularfire

请参阅下面的更新

我有一个角度应用程序,在该控制器的页面上有一个控制器和一个指令,它们都引用相同的firebase数据(我有充分的理由将它们分开)。当我对一个引用进行更改时,除非保存数据,否则其他引用不会反映更改。在不必保存数据的情况下更新所有本地firebase引用的最佳方法是什么。我想让用户在保存之前看看他/她的变化是什么样的。

我有一个能说明我遇到问题的傻瓜。键入一个输入,其他输入都不会更新,直到您保存。我希望他们都能在用户输入时保持同步。

http://jsfiddle.net/dberringer/F7MVB/2/

function MyCtrl($scope, $firebase) {
    var ref1 = $firebase(new Firebase("https://fiddler.firebaseio.com/test1"));
    ref1.$on('value', function () {
        $scope.foo = ref1;
    });

    $scope.save1 = function () {
        ref1.$save();
    };

    var ref2 = $firebase(new Firebase("https://fiddler.firebaseio.com/test1"));
    ref2.$on('value', function () {
        $scope.bar = ref2;
    });

    $scope.save2 = function () {
        ref2.$save();
    };

    $scope.bas = $firebase(new Firebase("https://fiddler.firebaseio.com/test1"));
    $scope.saveBas = function () {
        $scope.bas.$save();
    };

    $scope.biz = $firebase(new Firebase("https://fiddler.firebaseio.com/test1"));
    $scope.saveBiz = function () {
        $scope.biz.$save();
    };
}

谢谢!

更新 抱歉。我应该更清楚。我发布的小提琴只是一种快速而肮脏的方式来说明问题。这里有一个更准确的情况表示,以及为什么能够在不保存的情况下传播更改会有所帮助。我试图弄清楚是否有一种开箱即用的方法将一个firebase引用上的更改传播到另一个firebase引用,而无需用户将数据保存到firebase。也许我需要触发一个方法或事件来告诉所有更新的引用以匹配a。那会很好。

正如您所看到的,我的所有模型逻辑都在myModel工厂中。我的控制器很好而且很薄。 my-things指令可能存在也可能不存在于任何给定页面上,因此该指令直接访问模型而不是通过控制器的范围。我的控制器不需要为他们可能需要或可能不需要的指令注入一堆模型。在使用firebase时,走这条路线感觉非常干净自然。如果这是不可能的,人们是否有另一种方法来装配模型,与firebase资源交互,这将有助于此?再次感谢!

http://jsfiddle.net/dberringer/F7MVB/5/

angular.module('myApp',['firebase'])
    .factory('myModel', function ($q, $firebase) {
        var fbRef = $firebase(new Firebase("https://fiddler.firebaseio.com/"));
        return {
            getThings: function (id) {
                var deferred = $q.defer(),
                    ref1 = fbRef.$child(id);

                // Resolves the promise once the data is loaded from firebase
                ref1.$on('loaded', function (data) {
                    deferred.resolve(ref1);
                });

                return deferred.promise;
            }
        }
    })

    .directive('myThings', function (myModel) {
        return {
            template:   '<div>Hello, {{thingsListB.thing1}}!</div>',
            restrict: 'A',
            scope: {
                elemId: '@myThings'
            },
            link: function postLink(scope, iElement, iAttr) {
                myModel.getThings(scope.elemId).then(function (things) {
                    scope.thingsListB = things;
                });
            }
        }
    })

    .controller('myCtrl1', function($scope, myModel) {
        myModel.getThings('test1').then(function (things) {
            $scope.thingsListA = things;
        });

        // Something like this might do the trick
        // $scope.$watch('thingsListA', function () {
        //  $scope.thingsListA.$heyIChanged();
        // });
    })

    .controller('myCtrl2', function($scope) {
        $scope.foo = 'foo';
    });

1 个答案:

答案 0 :(得分:5)

这里有几件事:

致电$firebase(ref)会自动加载数据

当您使用引用调用AngularFire绑定$firebase时,它会自动加载数据。 在这种情况下,相同的数据被加载四次

编辑:从AngularFire 0.8开始,这已不再适用。要加载数据电话$asObject()$asArray()

ng-model本地同步,然后在准备好后保存到Firebase

要使数据在本地同步,我们不需要使用多个AngularFire绑定。只需使用ng-model和相同的保存功能,我们就可以在本地同步。一旦数据准备好保存到Firebase,我们就可以处理该操作。

我们可以通过使用一个AngularFire绑定并监听它的变化来简化它。要让更改在本地同步,我们可以共享相同的ng-model以及相同的save函数。

JSFiddle Demo

var myApp = angular.module('myApp',['firebase']);

function MyCtrl($scope, $firebase) {
    var ref1 = $firebase(new Firebase('https://fiddler.firebaseio.com/test1'));

    $scope.thing1 = '';

    ref1.$on('value', function(data) {
       $scope.thing1 = data.snapshot.value.thing1;
    });

    $scope.save = function () {
        ref1.$child('thing1').$set($scope.thing1);
    };
}

查看

<div ng-controller="MyCtrl">
    <div>Hello, {{thing1}}!</div>
    <input type="text" ng-model="thing1"/>
    <button ng-click="save()">Save 1</button>

    <div>Hello, {{thing1}}!</div>
    <input type="text" ng-model="thing1"/>
    <button ng-click="save()">Save 2</button>

    <div>Hello, {{thing1}}!</div>
    <input type="text" ng-model="thing1"/>
    <button ng-click="save()">Save 3</button>

    <div>Hello, {{thing1}}!</div>
    <input type="text" ng-model="thing1"/>
    <button ng-click="save()">Save 4</button>
</div>

来自您的更新

我上面提到的内容仍然适用。您要做的是在Firebase实例中“同步”数据而不保存。它不起作用。 $firebase绑定会立即加载Firebase在该位置的所有数据。因此,您无法“本地”同步它们。

然而,这没关系,因为我们仍然可以使用Angular在本地进行同步,然后在准备好后提交数据。

在你的指令中,我们实际上可以摆脱模型和链接功能。现在,该指令基本上变为ng-bind

JSFiddle Demo

.directive('myThings', function (myModel) {
    return {
        template:   '<div>Hello, {{myThings}}!</div>',
        restrict: 'A',
        scope: {
            myThings: '@'
        },
        link: function postLink(scope, iElement, iAttr) {

        }
    }
})

然后在视图中将属性my-things更改为使用绑定。

<div ng-controller="myCtrl1">
    <div>This is page 1</div>
    <div>Hello, {{thingsListA.thing1}}!</div>
    <input type="text" ng-model="thingsListA.thing1"/>
    <button ng-click="thingsListA.$save()">Save</button>

    <div my-things="{{thingsListA.thing1}}"></div>
</div>

这种方式更清晰,因为我们在then指令和控制器之间共享属性,而不是在两个地方创建它。