如何使用AngularJS过滤Firebase JSON?

时间:2016-11-15 08:18:30

标签: angularjs json firebase firebase-realtime-database

我在AngularJS中调用我的Firebase数据库JSON并尝试过滤代码。我一直看到Array错误,如:

Error: [filter:notarray] http://errors.angularjs.org/1.4.9/filter/notarray?

我的HTML:

<form>
      <div class="form-group">
        <div class="input-group">
          <div class="input-group-addon"><i class="fa fa-search"></i></div>
          <input type="text" class="form-control" placeholder="Search" ng-model="searchTranslation">
        </div>      
      </div>
    </form>

    <table class="table table-bordered table-striped">
        <thead>
            <tr>
                <th>ID</th>
                <th>English</th>
                <th>Arabic</th>
                <th>Status</th>
                <th>Settings</th>
            </tr>
        </thead>
        <tbody>
            <tr ng-repeat="i in translations | filter:searchTranslation track by $index">

                <td>{{$index}}</td>
                <td>{{i.transNameEn}}</td>
                <td class="textarabic">{{i.transNameArabic}}</td>
                <td class="{{i.transStatus}}">{{i.transStatus}}</td>
                <td>
                    <a ng-href="{{url}}pages-edit-translation/{{i.transId}}"
                    class="btn caps btn-warning">
                    EDIT
                    </a>
                </td>
            </tr>
        </tbody>
    </table>

我的JS代码

// @pages-home-translation
cmsApp.controller('pages-home-translation', function ($scope, $http) {

    $scope.sortType     = 'English'; // set the default sort type
    $scope.sortReverse  = false;  // set the default sort order
    $scope.searchTranslation   = '';     // set the default search/filter term

    $http.get(firebase_url+'cms/translations.json'+randstatus).success(function(data) {
        $scope.translations=data; // or data.data
    });

});

我的JSON:

{
    "00hym5km2tf08s38fr-ivjgnsw6": {
        "notes": "",
        "transCreation": "11/15/2016, 4:14:07 PM",
        "transId": "00hym5km2tf08s38fr-ivjgnsw6",
        "transModified": "11/15/2016, 4:14:07 PM",
        "transNameArabic": "استخدم كعنوان الدفع الافتراضي",
        "transNameEn": "Use as my default billing address",
        "transStatus": "FIXED"
    },
    "08zq3t9411zaketnpnwmi-ivjhzz5q": {
        "notes": "",
        "transCreation": "11/15/2016, 4:51:35 PM",
        "transId": "08zq3t9411zaketnpnwmi-ivjhzz5q",
        "transModified": "11/15/2016, 4:51:35 PM",
        "transNameArabic": "احذية كرة القدم",
        "transNameEn": "Football Shoes",
        "transStatus": "FIXED"
    },
    "0aoycw0b0c9v8ov6xbt9-ivjhwnv6": {
        "notes": "",
        "transCreation": "11/15/2016, 4:49:00 PM",
        "transId": "0aoycw0b0c9v8ov6xbt9-ivjhwnv6",
        "transModified": "11/15/2016, 4:49:00 PM",
        "transNameArabic": "جينز واسع",
        "transNameEn": "Flared Jeans",
        "transStatus": "FIXED"
    }
}

注意:如果我删除

<tr ng-repeat="i in translations | filter:searchTranslation track by $index">

并执行此操作而不是:

<tr ng-repeat="i in translations">

但显然我希望使用搜索表单过滤结果。使用data.data显示控制台中没有错误。

我曾尝试在setTimeOut上执行http.get并且还会延迟,以便首先加载JSON,但它仍无效。

由于

2 个答案:

答案 0 :(得分:3)

问题是filter默认情况下不会过滤对象,即使ng-repeat可以迭代对象属性。因此,这个问题有两种方法:在将对象设置为模型之前将对象转换为数组,或者可以创建自定义过滤器(不太可重复使用)来过滤对象属性。

第一

要创建自定义过滤器,您可以执行以下操作:

Html

<ANY ng-repeat="item in items | filterObject:myModel">

JS

angular.filter('filterObject', function () {
    return function (obj, myModel) {
        // filter logic, bla bla bla
    };
});

第二

要将对象转换为数组,可以在控制器端执行(或创建辅助函数,服务等),也可以创建自定义过滤器来执行此操作。例如:

Html

<ANY ng-repeat="item in items | asArray | filter:myModel">

JS

.filter('asArray', function() {
  return function(obj /*, addKey*/ ) {
    // in case of undefined just return the same object to pass through
    if (!obj) return obj;
    // return an object maped as array of key as an item
    return Object.keys(obj).map(function(key) {
      return obj[key];
    });
  };
});

使用过滤器将数组转换为对象,您可以重用$filter逻辑,而无需再次实现过滤器解决方案。因此,我认为这比为任务使用自定义过滤器更好。

稍微便宜的方法是在将其发送到模型之前将其转换为数组。但是,您可能希望保留原始属性名称(ID或其他任何内容)。

$http.get(firebase_url+'cms/translations.json'+randstatus).success(function(data) {    
    var myData = Object.keys(data).map(function(key) {
        return obj[key];
    });    
    $scope.translations = myData;    
});

以下示例使用第二种方法(模拟服务器响应的1秒延迟或填充translations模型的内容)实现此解决方案:

&#13;
&#13;
var cmsApp = angular.module('cmsApp', []);

cmsApp.filter('asArray', function() {
  return function(obj /*, addKey*/ ) {
    // in case of undefined just return the same object to pass through
    if (!obj) return obj;
    // return an object maped as array of key as an item
    return Object.keys(obj).map(function(key) {
      return obj[key];
    });
  };
});

// @pages-home-translation
cmsApp.controller('pages-home-translation', function($scope, $http, $timeout) {

  $scope.sortType = 'English'; // set the default sort type
  $scope.sortReverse = false; // set the default sort order
  $scope.searchTranslation = ''; // set the default search/filter term

  var data = {
    "00hym5km2tf08s38fr-ivjgnsw6": {
      "notes": "",
      "transCreation": "11/15/2016, 4:14:07 PM",
      "transId": "00hym5km2tf08s38fr-ivjgnsw6",
      "transModified": "11/15/2016, 4:14:07 PM",
      "transNameArabic": "استخدم كعنوان الدفع الافتراضي",
      "transNameEn": "Use as my default billing address",
      "transStatus": "FIXED"
    },
    "08zq3t9411zaketnpnwmi-ivjhzz5q": {
      "notes": "",
      "transCreation": "11/15/2016, 4:51:35 PM",
      "transId": "08zq3t9411zaketnpnwmi-ivjhzz5q",
      "transModified": "11/15/2016, 4:51:35 PM",
      "transNameArabic": "احذية كرة القدم",
      "transNameEn": "Football Shoes",
      "transStatus": "FIXED"
    },
    "0aoycw0b0c9v8ov6xbt9-ivjhwnv6": {
      "notes": "",
      "transCreation": "11/15/2016, 4:49:00 PM",
      "transId": "0aoycw0b0c9v8ov6xbt9-ivjhwnv6",
      "transModified": "11/15/2016, 4:49:00 PM",
      "transNameArabic": "جينز واسع",
      "transNameEn": "Flared Jeans",
      "transStatus": "FIXED"
    }
  };

  $timeout(function() {
    $scope.translations = data; // or data.data
  }, 1500);

});

angular.element(document).ready(function() {
  angular.bootstrap(document, ['cmsApp']);
});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.js"></script>
<div ng-controller="pages-home-translation">
  <form>
    <div class="form-group">
      <div class="input-group">
        <div class="input-group-addon"><i class="fa fa-search"></i>
        </div>
        <input type="text" class="form-control" placeholder="Search" ng-model="searchTranslation">
      </div>
    </div>
  </form>

  <table class="table table-bordered table-striped" border="1" cellpadding="4" style="border-collapse: collapse;">
    <thead>
      <tr>
        <th>ID</th>
        <th>English</th>
        <th>Arabic</th>
        <th>Status</th>
        <th>Settings</th>
      </tr>
    </thead>
    <tbody>
      <tr ng-repeat="i in translations | asArray | filter:searchTranslation track by $index">

        <td>{{$index}}</td>
        <td>{{i.transNameEn}}</td>
        <td class="textarabic">{{i.transNameArabic}}</td>
        <td class="{{i.transStatus}}">{{i.transStatus}}</td>
        <td>
          <a ng-href="{{url}}pages-edit-translation/{{i.transId}}" class="btn caps btn-warning">EDIT</a>
        </td>
      </tr>
    </tbody>
  </table>
</div>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

根据您的代码需要进行一些更改。首先$scope.translations应该是一个数组,但根据你的JSON,它不是一个数组。 ng-repeat指令只接受一个数组来重复data

根据您的$scope.translations结构,您的HTML应该是这样的:

$scope.translations = [
  {
    "notes": "",
    "transCreation": "11/15/2016, 4:14:07 PM",
    "transId": "00hym5km2tf08s38fr-ivjgnsw6",
    "transModified": "11/15/2016, 4:14:07 PM",
    "transNameArabic": "استخدم كعنوان الدفع الافتراضي",
    "transNameEn": "Use as my default billing address",
    "transStatus": "FIXED"
  },
  {
    "notes": "",
    "transCreation": "11/15/2016, 4:51:35 PM",
    "transId": "08zq3t9411zaketnpnwmi-ivjhzz5q",
    "transModified": "11/15/2016, 4:51:35 PM",
    "transNameArabic": "احذية كرة القدم",
    "transNameEn": "Football Shoes",
    "transStatus": "FIXED"
  },
  {
    "notes": "",
    "transCreation": "11/15/2016, 4:49:00 PM",
    "transId": "0aoycw0b0c9v8ov6xbt9-ivjhwnv6",
    "transModified": "11/15/2016, 4:49:00 PM",
    "transNameArabic": "جينز واسع",
    "transNameEn": "Flared Jeans",
    "transStatus": "FIXED"
  }
];

工作演示:

&#13;
&#13;
var cmsApp = angular.module('myApp',[]);
cmsApp.controller('pages-home-translation', function ($scope, $http) {

    $scope.sortType     = 'English'; // set the default sort type
    $scope.sortReverse  = false;  // set the default sort order
    $scope.searchTranslation   = '';     // set the default 
    
    $scope.translations = [
    {
        "notes": "",
        "transCreation": "11/15/2016, 4:14:07 PM",
        "transId": "00hym5km2tf08s38fr-ivjgnsw6",
        "transModified": "11/15/2016, 4:14:07 PM",
        "transNameArabic": "استخدم كعنوان الدفع الافتراضي",
        "transNameEn": "Use as my default billing address",
        "transStatus": "FIXED"
    },
    {
        "notes": "",
        "transCreation": "11/15/2016, 4:51:35 PM",
        "transId": "08zq3t9411zaketnpnwmi-ivjhzz5q",
        "transModified": "11/15/2016, 4:51:35 PM",
        "transNameArabic": "احذية كرة القدم",
        "transNameEn": "Football Shoes",
        "transStatus": "FIXED"
    },
    {
        "notes": "",
        "transCreation": "11/15/2016, 4:49:00 PM",
        "transId": "0aoycw0b0c9v8ov6xbt9-ivjhwnv6",
        "transModified": "11/15/2016, 4:49:00 PM",
        "transNameArabic": "جينز واسع",
        "transNameEn": "Flared Jeans",
        "transStatus": "FIXED"
    }
];
    
});
&#13;
table,th,td {
  border:1px solid black;
  }
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="pages-home-translation">
  <form>
      <div class="form-group">
        <div class="input-group">
          <div class="input-group-addon"><i class="fa fa-search"></i></div>
          <input type="text" class="form-control" placeholder="Search" ng-model="searchTranslation">
        </div>      
      </div>
    </form>

    <table class="table table-bordered table-striped">
        <thead>
            <tr>
                <th>ID</th>
                <th>English</th>
                <th>Arabic</th>
                <th>Status</th>
                <th>Settings</th>
            </tr>
        </thead>
        <tbody>
            <tr ng-repeat="i in translations | filter:searchTranslation">

                <td>{{$index}}</td>
                <td>{{i.transNameEn}}</td>
                <td class="textarabic">{{i.transNameArabic}}</td>
                <td class="{{i.transStatus}}">{{i.transStatus}}</td>
                <td>
                    <a ng-href="{{url}}pages-edit-translation/{{i.transId}}"
                    class="btn caps btn-warning">
                    EDIT
                    </a>
                </td>
            </tr>
        </tbody>
    </table>
</div>
&#13;
&#13;
&#13;