简体   繁体   English

推迟Angular直到收到Firebase数据

[英]Deferring Angular until Firebase data received

Right now, I am having users input data on the a sign up page, which includes having the user input their "plan type". 现在,我正在让用户在注册页面上输入数据,其中包括让用户输入他们的“计划类型”。 I store this user data on Firebase. 我将此用户数据存储在Firebase上。

On the following page after the user has submitted the previous input page, I take the user to an output page that uses AngularJS to show all plans filtered by the user's "plan type" (in the code, it's the customFilter). 在用户提交了上一个输入页面后的下一页上,我将用户带到一个输出页面,该页面使用AngularJS显示由用户的“计划类型”过滤的所有计划(在代码中,它是customFilter)。 So, as soon as the page loads, I want to be able to call the user's plan type from firebase and then make it the initial filter that customFilter uses. 因此,一旦页面加载,我希望能够从firebase调用用户的计划类型,然后使其成为customFilter使用的初始过滤器。

How do I get the Angular filter to wait until I get the "plan type' from Firebase? Any examples would be much appreciated. 如何让Angular过滤器等到我从Firebase获得“计划类型”?任何例子都会非常感激。

I've added the code below to make this easier to answer** 我已添加以下代码,以便更容易回答**

<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 app code here 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;
    }
  };  
})      

I tried to simulate your call to your firebase. 我试图模拟你对你的火力架的召唤。

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

html 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>

I keep the filtered list to be able to display a message if there is no items. 我保留过滤后的列表,以便在没有项目的情况下显示消息。

js 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;
  };
});

Resolve the fireBase Data on the route. 解析路由上的fireBase数据。 This will prohibit the controller from loading before the data is present. 这将禁止控制器在数据出现之前加载。 Then just inject the data into the controller and continue forward with your normal process. 然后将数据注入控制器并继续正常进程。

I'm not going to write it using your variables, but an exmaple of such a config file would look like: 我不会使用你的变量来编写它,但是这样的配置文件的例子看起来像:

'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();
      }
    }
  });
});

Then Your controller would look something like this: 然后您的控制器看起来像这样:

'use strict';
angular.module('someModule.dashboard')
  .controller('dashBoardCtrl', function($scope, currentUser, userList){
   $scope.userList = userList;
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM