使用查询AngularFire检索记录

时间:2015-03-20 10:48:26

标签: angularjs firebase angularfire

我使用Firebase,Backend-as-a-Service作为我的网站应用程序,由AngularJS编程。

我想使用数据库查询来获取记录,例如:WHERE name == 'The Legend Of Korra'

我在Firebase服务器中有一系列电视剧, JSON CODE

{
  "series" : {
    "-JkqSvwyDw5F9DvGUu6b" : {
      "createdAt" : 1426842959884,
      "creators" : "Michael Dante DiMartino,Bryan Konietzko",
      "description" : "The series follows the adventures of protagonist twelve-year-old Aang and his friends, who must bring peace and unity to the world by ending the Fire Lord's war against the other three nations.",
      "episode_reset" : true,
      "genres" : "Action,Adventure,Fantasy,Comedy-drama",
      "keywords" : "avatar,the last airbender",
      "name" : "Avatar: The Last Airbender",
      "official_website" : "http://nicktoons.nick.com/shows/avatar",
      "publish_date" : "2005-02-21",
      "updatedAt" : 1426843055127
    }
  }
}

我现在使用的代码可以解决这个问题:

$scope.isSeriesValid = function(seriesName) {
    var seriesRef = new Firebase('http://<<firebaseapp>>.firebaseio.com/series');
    var seriesCollection = $firebaseArray(seriesRef);
    seriesCollection.$loaded(function() {
        angular.forEach(seriesCollection, function(seriesObject, index) {
            if(seriesObject.name == seriesName)
                return true;
        });
    });
    return false;
};

我想在不使用$firebaseArrayforEach的情况下完成这项工作。我该怎么做?

就像这样:

var seriesRef = new Firebase('http://<<firebaseapp>>.firebaseio.com/series');
var seriesObject = $firebaseObject(seriesRef.query({ name: seriesName }));

1 个答案:

答案 0 :(得分:20)

我有一些建议可能对此有所帮助:

实施例

  • 查看此工作PLNKR example
    • 我在我的一个公开Firebase实例中复制了您的数据。
    • 您正在寻找的查询是seriesCollectionRef.orderByChild("name").equalTo(seriesName)
    • 如果您输入&{39; Avatar: The Last Airbender&#39;在输入中单击&#34;查找&#34;,您将获得匹配的系列对象。
  • 在我的示例中,我扩展了$firebaseArray服务,以包含按名称查找特定系列的方法。
    • 请参阅extending AngularFire services
    • 的文档
    • 您可以在不扩展服务的情况下完成同样的事情,请参阅最后一个代码段。

工厂

app.factory('SeriesFactory', function(SeriesArrayFactory, fbUrl){
  return function(){
    var ref = new Firebase(fbUrl+'/series');
    return new SeriesArrayFactory(ref);
  }
});

app.factory('SeriesArrayFactory', function($firebaseArray, $q){
  return $firebaseArray.$extend({
    findSeries:function(seriesName){
      var deferred = $q.defer();
      // query by 'name'
      this.$ref().orderByChild("name").equalTo(seriesName).once("value", function(dataSnapshot){
        if(dataSnapshot.exists()){
          deferred.resolve(dataSnapshot.val());
        } else {
          deferred.reject("Not found.");
        }
      });
      return deferred.promise;
    }
  });
});

控制器

app.controller('HomeController',function($scope, SeriesFactory, fbUrl) {

  $scope.seriesName = '';

  $scope.findSeries = function() {
    console.log("Finding series with name:'",$scope.seriesName,"'");
    var seriesCollection = new SeriesFactory();
    seriesCollection.findSeries($scope.seriesName).then(function(data){
      console.log("Found",data);
      $scope.series = data;
    }).catch(function(error){
      console.warn(error);
    });
  };

});

没有扩展服务

如果你没有使用工厂,这就是控制器功能的样子:

  $scope.findSeriesWithoutFactory = function() {
    var seriesRef = new Firebase(fbUrl+'/series');
    var seriesCollection = $firebaseArray(seriesRef);
    seriesCollection.$ref().orderByChild("name").equalTo($scope.seriesName).once("value", function(dataSnapshot){
        var series = dataSnapshot.val();
        if(dataSnapshot.exists()){
          console.log("Found", series);
          $scope.series = series;
        } else {
          console.warn("Not found.");
        }
    });
  };

规则

注意:请注意,您应该将".indexOn":"name"添加到Firebase规则中,以便查询有效运行,这一点非常重要。像这样:

  "yourfirebaseapp": {
    ".read": "...",
    ".write": "...",
    "series": {
      ".indexOn": "name"
    }
  }

希望有所帮助!