Jim Lowell
Jim Lowell

Reputation: 328

What's the correct Angular / Firebase way to edit one object at a time from a list of objects?

I have an Angular / Firebase application that lets the user select a part from a list of parts. Each part has multiple fields and I want the user to be able to edit the fields for the part they pick. Everything should be 3-way bound to Firebase and all updates synced automatically.

My Firebase data would look like this:

{
  "partList": {
    "part1": {
      "field1": "value1",
      "field2": "value2",
      "field3": "value3"
    },
    "part2": {
      "field1": "value1",
      "field2": "value2",
      "field3": "value3"
    },
    "part3": {
      "field1": "value1",
      "field2": "value2",
      "field3": "value3"
    }
  }
}

Listing the parts is done with this ng-repeat:

<div ng-repeat="(key,value) in partList">{{key}}</div>

However, I'm not sure how to add form fields for the 3 fields on each part and have them correctly bind to the proper part when the user clicks on one in the list.

I tried using $bindTo with a $scope variable to the correct Firebase child when a part was clicked, but calling $bindTo more than once on the same scope variable resulted in a weird state where multiple objects in Firebase seemed to be bound to each other and seemed not to work (e.g. the previous bind didn't stop when I did more binds).

I can copy the object to a different $scope variable and then model that object to my input fields, but I lose 3-way binding when I do that and have to update Firebase manually.

What is the correct way to do this?

Upvotes: 3

Views: 232

Answers (1)

steveo
steveo

Reputation: 365

AngularJS handles the binding with a simple directive. For a form input, you would use "ng-model", and with a clickable link, you can use "ng-click". I'm not familiar with Firebase, so I can't address your 3-way binding issue without seeing the rest of your code.

You could inject these values into the global scope, but it is better practice not to, especially if you are writing a large app.

Also, you may want to consider converting your data to an array of objects like I've done in my script.js below. I'm not saying it's the only way, but it seems like it would be much simpler to do what you're trying to accomplish.

Here's my Index.Html:

<!DOCTYPE html >
<html data-ng-app="myApp">

<head>
  <script data-require="[email protected]" data-semver="2.1.3" src="http://code.jquery.com/jquery-2.1.3.min.js"></script>
  <link data-require="bootstrap@*" data-semver="3.3.2" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" />
  <script data-require="bootstrap@*" data-semver="3.3.2" src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
  <script data-require="angular.js@*" data-semver="1.4.0-beta.6" src="https://code.angularjs.org/1.4.0-beta.6/angular.js"></script>
  <link rel="stylesheet" href="style.css" />
  <script src="script.js"></script>
</head>

<body data-ng-controller="MainController as mc">
  <h3>Select Part</h3>
  <div ng-repeat="part in mc.partList">
    <a href ng-click="mc.selectPart(part)">{{part.id}} </a>
    <ul>

      <li >{{part.field1}}</li>
      <li>{{part.field2}}</li>
      <li>{{part.field3}}</li>
    </ul>
  </div>

<form action="">
  <h3>Edit Part</h3>
  Selected Part = {{mc.selectedPart.id}}
  <br><br>
  Field 1:  <input type="text" ng-model="mc.selectedPart.field1">
  <br><br>
  Field 2:  <input type="text" ng-model="mc.selectedPart.field2">
  <br><br>
  Field 3:  <input type="text" ng-model="mc.selectedPart.field3">
  <br><br>
  <input type="submit"> <!--TODO Wire up the submit button to bind data to a data access layer-->
</form>
</body>

</html>

And the Script.js

(function() {

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

  app.controller('MainController', MainController);

 function MainController() {
    var me = this;

     me.partList = [{
      "id": "part1",
      "field1": "value1",
      "field2": "value2",
      "field3": "value3"
    }, {
      "id": "part2",
      "field1": "value1",
      "field2": "value2",
      "field3": "value3"
    }, {
      "id": "part3",
      "field1": "value1",
      "field2": "value2",
      "field3": "value3"
    }];

  me.selectPart=  function(part) {
      me.selectedPart = part;
  };  
  }
})();

Upvotes: 1

Related Questions