【问题标题】:What's the correct Angular / Firebase way to edit one object at a time from a list of objects?从对象列表中一次编辑一个对象的正确 Angular / Firebase 方法是什么?
【发布时间】:2015-03-23 18:12:20
【问题描述】:

我有一个 Angular / Firebase 应用程序,它允许用户从部件列表中选择一个部件。每个部分都有多个字段,我希望用户能够编辑他们选择的部分的字段。一切都应该三向绑定到 Firebase,并且所有更新都会自动同步。

我的 Firebase 数据如下所示:

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

通过这个 ng-repeat 列出部件:

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

但是,我不确定如何为每个部分的 3 个字段添加表单字段,并在用户单击列表中的一个时将它们正确绑定到正确的部分。

当单击某个部件时,我尝试将带有 $scope 变量的 $bindTo 用于正确的 Firebase 子级,但是在同一个范围变量上多次调用 $bindTo 会导致一种奇怪的状态,即 Firebase 中的多个对象似乎被绑定彼此之间似乎不起作用(例如,当我进行更多绑定时,之前的绑定并没有停止)。

我可以将对象复制到不同的 $scope 变量,然后将该对象建模到我的输入字段,但是这样做时我会丢失 3 路绑定,并且必须手动更新 Firebase。

这样做的正确方法是什么?

【问题讨论】:

  • “所有内容都应该三向绑定到 Firebase,并且所有更新都会自动同步。”这是一种方便,而且很好,不是您的应用程序的要求。您可以调用 $save() 来应用更改,不要过分急于尝试使用 $bindTo 来解决每个问题。

标签: javascript angularjs firebase


【解决方案1】:

AngularJS 使用一个简单的指令来处理绑定。对于表单输入,您可以使用“ng-model”,并且通过可点击的链接,您可以使用“ng-click”。我对 Firebase 不熟悉,因此如果不查看您的其余代码,我无法解决您的 3 向绑定问题。

您可以将这些值注入全局范围,但最好不要这样做,尤其是在您编写大型应用程序时。

此外,您可能需要考虑将数据转换为对象数组,就像我在下面的 script.js 中所做的那样。我并不是说这是唯一的方法,但似乎做你想要完成的事情会简单得多。

这是我的 Index.Html:

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

<head>
  <script data-require="jquery@2.1.3" 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>

还有 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;
  };  
  }
})();

【讨论】:

  • 谢谢!这与我最初实现的非常接近,并且与 Angular 的 2 路数据绑定配合得很好,但是当(在您的示例中)me.partList 绑定到 Firebase 对象时,3 路数据绑定没有扩展到“selectedPart”,这是不是我所期望的。我会使用数组,但 Firebase 可以更好地处理对象,所以在这种情况下我使用对象。这个应用程序已经变得中等大小,所以我认为值得回到基础并尝试在 Plunker 中创建一个最小失败的测试用例。如果/当我让它工作(或失败)时,我会在这里发布它。
  • 我只是稍微浏览了一下 Firebase 的文档。我没有时间深入研究它的编码,但看起来他们建议将您的数据类型格式化为数组。 “同步数组应该用于任何将被排序、迭代并具有唯一 ID 的对象列表。同步数组假定项目是使用 $add() 添加的,因此它们将使用 Firebase 推送 ID 进行键控。 " “我们使用 $firebaseArray 服务创建了一个同步数组。”
  • 很明显,3 路绑定可能会在网络上变得“健谈”,频繁往返服务器以存储和获取数据。如果您只打算在本地或 Intranet 上运行它,这不是什么大问题,但我不建议将它用于移动应用程序或任何带宽有限的东西。祝你好运!!!
  • 昨天我能够创建一个可重复的失败案例,当我对在文本或文本区域表单控件中编辑的变量进行三向绑定时,Firebase 同步将失败。使用上面显示的方法进行同步非常有效。我的临时解决方案是使用 Angular 绑定到 $scope 变量,该变量不是 3 路绑定到 Firebase,然后在字段空闲 1 秒时使用 $timeout 更新 Firebase。我还将在 Plunker 中创建一个最小失败示例。完成后我会在这里发布。感谢您的帮助!
猜你喜欢
  • 2017-04-25
  • 2016-04-24
  • 2010-10-03
  • 2014-08-11
  • 2012-01-13
  • 1970-01-01
  • 2017-01-31
  • 2017-11-01
  • 1970-01-01
相关资源
最近更新 更多