Question

The following code is getting data from Firebase and binding it to $scope:

'use strict';

angular.module('costumeQueenApp')
.controller('ActorByUserIdActorIdCtrl', function ($scope,$routeParams,FireRef) {
    var userId = $routeParams.user_id
    var actorId = $routeParams.actor_id
    var base = FireRef.actorById(userId, actorId) 
    $scope.base = base
    $scope.base.$bind($scope, 'actor')
})

And uses the following template code to display the data (Note: uses AngularUI-Bootstrap):

<accordion-group heading="Sizes">
    <div ng-repeat="(key, value) in actor.sizes">
           <label for="key">{{key}}</label> <input type="text" ng-model="value" />
    </div>
</accordion-group>

The problem is that three-way data-binding is not working for the items inside the ng-repeat div. If I have an input field that uses the fully-qualified field in an input field, e.g., actor.sizes.waist, everything works as expected.

How do I make the data binding work properly?

Was it helpful?

Solution

If you replace value then you have essentially done: $childScope.value = somethingNew. Like any other JavaScript reference, this dose not modify the contents of the original object.

To put it another way, setting value above is equivalent to this:

var items = [{label: 'a'}, {label: 'b'}, {label: 'c'}];
angular.forEach(items, function(v, k) {
   v = {foo: bar}; // does nothing to items! Only modifies the local variable `v`
});

You can fix this when using angularFire by using $set:

<accordion-group heading="Sizes">
    <div ng-repeat="(key, value) in sizes">
           <label for="key">{{key}}</label> <input type="text" ng-model="value" ng-change="actor.$child('sizes/'+key).$set(value)" />
    </div>
</accordion-group>

Note that ng-change feels a bit hackish here but investigating that didn't feel necessary to illustrate the solution.

Also, if you are using $bind to sync data, or you want to control the timing of the sync event, you can just set the data on the parent object without a $set call:

<accordion-group heading="Sizes">
    <div ng-repeat="(key, value) in sizes">
           <label for="key">{{key}}</label> <input type="text" ng-model="value" ng-change="actor.sizes[key] = value" />
    </div>
</accordion-group>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top