1

现在,我让用户在注册页面上输入数据,其中包括让用户输入他们的“计划类型”。我将此用户数据存储在 Firebase 上。

在用户提交上一个输入页面后的下一页上,我将用户带到一个输出页面,该页面使用 AngularJS 显示所有按用户的“计划类型”过滤的计划(在代码中,它是 customFilter)。因此,一旦页面加载,我希望能够从 firebase 调用用户的计划类型,然后使其成为 customFilter 使用的初始过滤器。

如何让 Angular 过滤器等到我从 Firebase 获得“计划类型”?任何示例将不胜感激。

我添加了下面的代码,以便更容易回答**

<body ng-app="tipOutput" ng-controller="Tips">
<div ng-controller="MainCtrl">
// Custom filter that I want to customize based on user data
   <span class="select">
      <select style="width:100%" ng-model="filterItem.plan" ng-options="item.name for item in filterOptions.plans"></select>
   </span>
// Table using ng-repeat and above filter
  <table>
    <tbody>
      <tr ng-repeat="tip in tips | filter:customFilter"> 
         <td style="vertical-align:top"><span><strong>{{tip.planName}}</strong></span><span ng-show="tip.planDetail">Plan Detail: {{tip.planDetail}}</span></td>
      </tr>
    </tbody>
  </table>
</div>
</body>

Angular 应用程序代码在这里

angular.module('tipOutput', ['firebase', 'filters'])
  .controller('Tips', ['$scope', 'angularFire', 
  function ($scope, angularFire) {
    var ref = new Firebase('https://sitename.firebaseio.com/tips');
    angularFire(ref, $scope, "tips");
  }])
 .controller('MainCtrl', function($scope) {

//Contains the filter options
  $scope.filterOptions = {
    plans: [
      {id : 2, name : 'All Plans', type: 'all' },
      {id : 3, name : 'Plan Type 1', type: 'plan-type-1' },
      {id : 4, name : 'Plan Type 2', type: 'plan-type-2' },
      {id : 5, name : 'Plan Type 3', type: 'plan-type-3' },
      {id : 6, name : 'Plan Type 4', type: 'plan-type-4' },
      {id : 7, name : 'Plan Type 5', type: 'plan-type-5' },
      {id : 8, name : 'Plan Type 6', type: 'plan-type-6' }  
    ]
  };
// Here's where the initial value of the filter is set. Currently, it's not dynamic, but I
// want it to be based off a variable that comes in asynchronously (i.e. likely after this
// code would otherwise run)
  $scope.filterItem = {
    plan: $scope.filterOptions.plans[0]
  }   
//Custom filter - filter based on the plan type selected
  $scope.customFilter = function (tip) {
    if (tip.servicesReceived === $scope.filterItem.plan.type) {
      return true;
    } else if ($scope.filterItem.plan.type === 'all') {
      return true;
    } else {
      return false;
    }
  };  
})      
4

2 回答 2

3

我试图模拟您对 Firebase 的调用。

演示http ://plnkr.co/edit/VDmTCmR82IyaKnfaT1CP?p=preview

html

<body ng-controller="MainCtrl">
<p>Hello {{name}}!</p>

<div>
  <span class="select">
    <select ng-model="filterItem.plan" ng-options="item.name for item in filterOptions.plans"></select>
  </span>

  <table border="1">
    <tbody>
      <tr ng-repeat="tip in (filtered = (tips | filter:customFilter))"> 
        <td>
          <span><strong>{{tip.planName}}</strong></span>
          <span>Plan Detail: {{tip.planDetail}}</span>
        </td>
      </tr>
      <tr ng-show="filtered.length==0">
        <td>None</td>
      </tr>
    </tbody>
  </table>

</div>
</body>

如果没有项目,我会保留过滤后的列表以显示消息。

js

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

app.controller('MainCtrl', function($scope, $timeout, angularFire) {
  $scope.name = 'World';
  $scope.tips = [];

  /*
  // since we dont have access to your firebase, i used a $timeout
  var ref = new Firebase('https://sitename.firebaseio.com/tips');

  // we wait for the callback of angularFire
  angularFire(ref, $scope, "tips").then(function(response) {
     var index = 1; // find the good index in filterOptions
     $scope.filterItem.plan = $scope.filterOptions.plans[index];
  });*/

  // simulate the response
  $timeout(function() {
      $scope.tips = [
        {planName: '213', planDetail:'534',servicesReceived:'plan-type-1'},
        {planName: '123', planDetail:'345',servicesReceived:'plan-type-2'},
        {planName: '321', planDetail:'643'} // this one has no serviceReceived
      ];
      // set it to the response receive from the server
      var response = 1;
      $scope.filterItem.plan = $scope.filterOptions.plans[response];
  }, 1000);

  $scope.filterOptions = {
    plans: [
      {id : 2, name : 'All Plans', type: 'all' },
      {id : 3, name : 'Plan Type 1', type: 'plan-type-1' },
      {id : 4, name : 'Plan Type 2', type: 'plan-type-2' },
      {id : 5, name : 'Plan Type 3', type: 'plan-type-3' },
      {id : 6, name : 'Plan Type 4', type: 'plan-type-4' },
      {id : 7, name : 'Plan Type 5', type: 'plan-type-5' },
      {id : 8, name : 'Plan Type 6', type: 'plan-type-6' }  
    ]
  };

  // default value
  $scope.filterItem = {
    plan: $scope.filterOptions.plans[0] // Do something with response
  }

  $scope.customFilter = function (tip) {
    return (tip.servicesReceived || 'all') === $scope.filterItem.plan.type;
  };
});
于 2013-10-15T22:07:34.460 回答
0

解析路由上的 fireBase 数据。这将禁止控制器在数据出现之前加载。然后只需将数据注入控制器并继续您的正常流程。

我不会使用您的变量来编写它,但是这样的配置文件的示例如下所示:

'use strict';

angular.module('someModule.dashboard')
 .config(function ($stateProvider){
  $stateProvider
  .state('dashboard', {
    url: '/dashboard',
    templateUrl: '/app/dashboard/html/dashboard.html',
    controller: 'dashBoardCtrl',
    resolve: {
      currentAuth: function(fireBaseAuth){
        return fireBaseAuth.auth().$requireAuth();
      },
      currentUser: function($fireBaseUser, Session){
       return $fireBaseUser.user(Session.id).$asObject();
      },
      userList: function($fireBaseUser){
        return $fireBaseUser.userList().$asArray();
      }
    }
  });
});

然后你的控制器看起来像这样:

'use strict';
angular.module('someModule.dashboard')
  .controller('dashBoardCtrl', function($scope, currentUser, userList){
   $scope.userList = userList;
});
于 2014-11-30T05:11:36.860 回答