【问题标题】:Data from firebase not loading on route change, but does on refresh来自firebase的数据不会在路由更改时加载,但会在刷新时加载
【发布时间】:2016-10-14 06:17:46
【问题描述】:

我正在使用 angularFire 和 Angular 来更新一些视图,但奇怪的是当我从视图切换到视图时数据不会加载,但当我刷新页面时它会加载。怎么回事?

向导控制器:

/* initialize data */

var ref = new Firebase('https://dlwj.firebaseio.com/');

/* set data to automatically update on change */

$scope.currentLocation = $route.current.$$route.originalPath;
$scope.propertyRef = $firebase(ref);

$scope.propertyRef.$on('loaded', function(value) {

  //value will be undefined when I switch views using hash routes.
  //there is no issue when I just refresh on that page.
  console.log(value); 
  $scope.propertyConfiguration = value.products;
  var products = [];
  for (var key in value.products) {
    if (value.products.hasOwnProperty(key)) {
      products.push(key);
    }
  }

  $scope.productsArray = products;

});

console.log('Data retrieved');

路线:

$routeProvider.when('/SharedProperties',
{
  templateUrl: 'partials/SharedPropertiesPartial.html',
  controller: 'WizardController'
});

$routeProvider.when('/Registration',
{
  templateUrl: 'partials/Registration.html',
  controller: 'WizardController'
});

$routeProvider.when('/Login',
{
  templateUrl: 'partials/Login.html',
  controller: 'WizardController'
});

【问题讨论】:

  • 这是什么版本的angularFire?为什么将值推入“已加载”内部的数组中,而不是让 $firebase 处理同步到 $scope.products?为什么我们使用数组?如果将 console.log 放在加载的回调中会发生什么;它只会在重新加载时触发而不是查看开关,对吧?
  • 版本为0.6.0。我不确定 $firebase 处理同步是什么意思,但我使用 firebase 作为静态数据源,所以我不希望 productsArray 改变。 'loaded' 回调中的 console.log() 始终运行,它要么在 view2view 开关上输出 undefined,要么在页面刷新时输出实际数据。
  • 尝试将console.log放入加载的回调中(目前在该方法之外)。
  • 我可能理解错了,但会不会像 $scope.propertyRef.$on('loaded', function(){console.log()}); 一样? B/c 那里已经有一个了。

标签: angularjs firebase angularfire


【解决方案1】:

没有理由使用 $firebase 之类的包装器库(负责同步等)下载数据,然后立即将这些数据拉出并放入不同的范围对象中。

只需声明你的作用域变量:

$scope.products = $firebase(ref);

并使用它:

<ul>
   <li ng-repeat="product in products | orderByPriority">{{product|json}}</li>
</ul>

如果您需要在控制器或服务中迭代数据:

$scope.products = $firebase(ref);

// some time later, probably in $scope.products.$on('loaded')...
// note that $getIndex() is only useful here to get the keys in
// the order they appear in the database, otherwise, forEach($scope.products, ...)
// is sufficient
angular.forEach($scope.products.$getIndex(), function(key) {
   console.log(key, $scope.products[key]);
});

如果您想将 Firebase 用作静态数据库(这对于像我这样的所有实时事物的爱好者来说非常令人困惑)并且每次发生更改时都不会收到通知,您可以简单地执行以下操作:

angular.controller('MyController', function($timeout, $scope) {
   new Firebase('<URL>').once('value', function(snap) {
      $timeout(function() {
         $scope.products = snap.val();
      });
   });
});

然后正常使用:

<ul>
   <li ng-repeat="(key,product) in products">{{key}}: {{product|json}}</li>
</ul>

【讨论】:

  • 感谢加藤,像往常一样提供更详细的答案!我实际上已经忘记了(密钥,产品),我所有的循环只是试图获取密钥的一种骇人听闻的方式。你确定你的$scope.products[key] 有效吗?它为我打印未定义。这与问题here 非常相似,其中对象在控制台中打印为{$method1,$method2,property1,property2},但object.property1 打印出未定义。
  • 找到你的答案here :) 需要将代码包装在 $on('loaded') 中。使用异步调用有点棘手。
  • 啊,对,您需要将其包装在 $on('loaded') 中。必须记住不要用速记编码:)
  • 为什么$timeout.once()、@Kato 里面?
  • @Kato 是对的,我遇到了同样的问题并想出了与这里相同的解决方案。它只是工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-16
  • 1970-01-01
  • 2011-05-15
  • 2013-01-31
  • 2019-01-18
相关资源
最近更新 更多