【问题标题】:Using ng-repeat to access an array of objects from firebase使用 ng-repeat 从 firebase 访问对象数组
【发布时间】:2015-03-16 05:09:19
【问题描述】:

我正在尝试使用 angularjs 从 firebase 访问笔记列表,但无法显示数据。控制台中没有抛出任何错误。

Notes.controller('ListGroupCtrl', ['$scope',
  function($scope) {
    NotesRef.on("child_added", function(snapshot) {
      var newNotes = snapshot.val();
      console.log("title: " + newNotes.Title);
    });
  }
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div class="list-group" id="list-group" ng-controller="ListGroupCtrl">
  <!-- List of Notes -->
  <div class="list-group-item" value="" ng-repeat="note in newNotes">
    <div class="list-note-title" ng-repeat="(key, val) in note">{{key}}: {{val}}</div>
  </div>
</div>

HTML 显示为:

<div class="list-group ng-scope" id="list-group" ng-controller="ListGroupCtrl">
  <!-- List of Notes -->
  <!-- ngRepeat: note in newNotes -->
</div>

console.log 行显示:

title: Title 1
title: Title 2
title: Title 3

Firebase 数据:

Notes:

-1:
   -title: Title 1
   -content: Content 1
-2:
   -title: Title 2
   -content: Content 2
-3:
   -title: Title 3
   -content: Content 3

目前,我已手动输入数据。但是,我将使用 Firebase 的 .set() 来随机生成 1、2、3。所以数据会变成……:

Notes:

-QWE39Poif8uDh:
   -title: Title 1
   -content: Content 1
-78DBn2ja8skHf:
   -title: Title 2
   -content: Content 2
-11oLkdwjHf8a9:
   -title: Title 3
   -content: Content 3

【问题讨论】:

  • 使用 if(!$scope.$$phase)$scope.$apply() bdw 什么是 NotesRef?

标签: arrays angularjs object firebase ng-repeat


【解决方案1】:

使用$scope 访问视图中的变量。

Notes.controller('ListGroupCtrl', ['$scope', function ($scope) { NotesRef.on("child_added", function(snapshot) { $scope.newNotes = snapshot.val(); //use $scope. console.log("title: " + $scope.newNotes.Title); }); }])

【讨论】:

  • 如何访问 $scope.newNotes.Title 以便在视图中更新数据?目前 .list-note-title div 没有显示,因为 {{key}}: {{val}} 没有正确填充数据。我只是不知道那是哪里坏了。
    {{key}}: {{val}}
  • 为什么不尝试在 HTML 中编写 newNotes = {{newNotes}} 以验证值是否已填充到 $scope.newNotes 中。不要在这里使用任何ng-repeat
【解决方案2】:

正如 Frank 所指出的,主要问题是,当新数据可用时,您没有更新范围。您可以通过将 angularjs $timeout 注入控制器来实现此目的。请参见下面的一个使用 Firebase Litecoin 汇率 API 的示例。

HTML 模板

<body ng-controller="RatesCtrl">
  Updated:
  <pre>{{ rate._updated }}</pre>
  Data:
  <pre><span ng-repeat="(key, val) in rate">{{ key }} : {{ val }}<br></span></pre>
  Raw:
  <span><pre>{{ rate | json }}</pre></span>
</body>

JavaScript

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

app.controller('RatesCtrl', function ($scope, $timeout) {
  var ratesRef = new Firebase('https://publicdata-cryptocurrency.firebaseio.com/litecoin');
  ratesRef.on('value', function (snapshot) {
    $timeout(function () {
      update(snapshot);
    });
  });

  function update (snapshot) {
    console.log('update fired');
    $scope.rate = snapshot.val();
  }
});

完美地显示和更新信息。

相关plunker在这里http://plnkr.co/edit/SUenBO


除此之外,我建议使用angular-fire,这会让你的生活变得更轻松。

HTML 模板

<body ng-controller="RatesCtrl">
  <div>
    Rate:
    <pre>Exchange rate is {{ rate.last }} at {{ rate._updated }}</pre>
    Raw:
    <pre>{{ rate | json }}</pre>
  </div>
</body>

JavaScript

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

app.controller('RatesCtrl', function ($scope, RatesService) {
  $scope.rate = RatesService.update();
});

app.factory('RatesService', function ($firebase) {
  var ref = new Firebase('https://publicdata-cryptocurrency.firebaseio.com/litecoin');

  return {
    update: function () { 
      console.log('update fired');
      return $firebase(ref).$asObject();
    }
  };
});

这会给你类似的东西

相关plunker可以在这里http://plnkr.co/edit/QvBHRX

【讨论】:

  • $interval 的棘手问题会每秒用on('value' 查询 Firebase,不是吗。虽然这可能有效,但它是一种轮询解决方案 - 与 Firebase 的服务器到客户端推送方法有些相反。
  • 感谢@FrankvanPuffelen 指出这一点。这是我第一次使用 Firebase 服务。相应地更新了答案。
【解决方案3】:

正如您所见,数据通过您拥有的代码进入您的客户端。但是 Angular 并没有意识到这一点,这意味着它不会更新视图。正如 Mikko 在他的回答中所说,这通常由 AngularFire 为您处理。此外,AngularFire 还将处理从 Firebase 在您调用 push 时生成的键到 Angular 的 ng-repeat 喜欢的常规数组索引的映射。

所以我建议使用 AngularFire。但在那之前,这应该足以让你更进一步:

Notes.controller('ListGroupCtrl', ['$scope', '$timeout',
  function($scope, $timeout) {
    NotesRef.on("child_added", function(snapshot) {
      var newNotes = snapshot.val();
      $timeout(function() {
        $scope.newNotes = snapshot.val();
      });
    });
  }
]);

$timeout 中运行代码可确保 Angular 之后更新所有受影响的视图。

现在 Firebase 文档中有一个关于这种类型的 Angular-without-AngularFire interaction 的不错的部分。

【讨论】:

  • $timeout 的注入失败,否则完美。
  • 糟糕,感谢您收听。我通常使用$scope.$apply 来完成相同的操作,并且不需要注入新变量。但仍然......固定。 :-)
  • 我可能会删除我的答案,因为您的答案现在涵盖了相同的解决方案并且更加详尽。
猜你喜欢
相关资源
最近更新 更多
热门标签