简体   繁体   English

在页面上任何内容前都解析2个数组

[英]Resolve 2 arrays before anything on the page with a promise

I have 2 arrays, sports and leagues and I want those arrays to become resolve before anything on the page, I will paste all of my code regarding those arrays I just mentioned. 我有2个数组,分别是sportsleagues ,我希望这些数组在页面上的任何内容之前都可以解决,我将粘贴与我刚才提到的数组有关的所有代码。 I need to do this due to an issue I am having with the Angular filters. 由于Angular过滤器存在问题,因此需要执行此操作。

this is my html 这是我的HTML

<div ng-repeat="sport in sportsFilter = (sports | filter:query)">
  <div ng-if="sport.leagues.length">
     <!--first array-->
     {{sport.name}}
  </div>
      <div ng-repeat="league in sport.leagues">
        <!--second array-->
        {{league.name}}
      </div>
    </div>

controller 控制者

  .controller('SportsController', function($scope, $state, AuthFactory,   
               SportsFactory, Sports) {

    $scope.sports = [];
    $scope.sportPromise = Sports;


    AuthFactory.getCustomer().then(function(customer) {
      $scope.customer = customer;
      SportsFactory.getSportsWithLeagues(customer).then(function(sports) {
        $ionicLoading.hide();
        if (sports.length) {

          $scope.sportPromise = Sports;

          $scope.sports = sports;

        }else {
          AuthFactory.logout();
        }
      }, function(err) {
        console.log(err);
      });
     }
    });

    $scope.isSportShown = function(sport) {
      return $scope.shownSport === sport;
    };

  });

and here de app.js so far, I thought with this I was resolving the arrays, actually the must important is the array named leagues , but still is giving me troubles 到目前为止,在de app.js上,我以为我正在解析数组,实际上必须要注意的是名为leagues的数组,但仍然给我带来了麻烦

.state('app.sports', {
  url:'/sports',
  views:{
    menuContent:{
      templateUrl:'templates/sportsList.html',
      controller:'SportsController',
      resolve: {
        Sports: function(SportsFactory, AuthFactory, $q) {
          var defer = $q.defer();

          AuthFactory.getCustomer().then(function(customer) {
            SportsFactory.getSportsWithLeagues(customer).then(function(sports) {

              var sportLeagues = _.pluck(sports, 'leagues'),
                  leaguesProperties = _.chain(sportLeagues).flatten().pluck('name').value();

              console.log(leaguesProperties);

              defer.resolve(leaguesProperties);

            });

          });
          return defer.promise;
        }
      }
    }
  }
})

UPDATE: 更新:

the page is loading and I my filter is getting the array leagues empty, so is not searching thru to it, so I need that array to load first than the filters. 该页面正在加载,我的过滤器正在使数组leagues空,因此没有进行搜索,因此我需要先加载该数组而不是过滤器。

Here's how this could work at a high-level, including avoiding some mistakes you are making. 这是在更高层次上的工作方式,包括避免您犯一些错误。

Mistakes: 错误:

  • You don't need to use $q.defer when the API you are using is already returning a promise. 当您使用的API已经返回了诺言时,您无需使用$q.defer Just return that promise. 只要兑现承诺。 What you are doing is called an deferred anti-pattern . 您正在执行的操作称为延迟反模式
  • resolve is used when you need to do something (like authentication) before you are hitting a particular state. 当您需要在达到特定状态之前需要执行某些操作(例如身份验证)时,可以使用resolve You are under-using the resolve by not resolving the customer , and instead doing this in the controller. 您没有通过解决customer resolve来充分利用resolve ,而是在控制器中这样做。
  • resolve property of $stateProvider can accept other resolves as parameters. resolve财产$stateProvider可以接受其他resolves作为参数。

With these out of the way, here's how it could work: 有了这些,它的工作方式如下:

.state('app.sports', {
  resolve: {
    customer: function(AuthFactory){
       return AuthFactory.getCustomer();
    },
    sports: function(SportsFactory, customer){
       return SportsFactory.getSportsWithLeagues(customer);
    },
    leagues: function(sports){
       var leagueProperties;

       // obtain leagueProperties from sports - whatever you do there.

       return leagueProperties;
    }
  }
});

Then, in the controller you no longer need AuthFactory - you already have customer : 然后,在控制器中,您不再需要AuthFactory您已经拥有了customer

.controller('SportsController', function($scope, customer, sports, leagues){
   $scope.sports = sports;
})

As per request in the comments of New Dev's answer the same only using array notation so that the code remains minifiable: 根据New Dev的注释中的请求,仅使用数组表示法可以使代码保持最小化:

.state('app.sports', {
    resolve: {
        customer: ['AuthFactory', function(AuthFactory){
            return AuthFactory.getCustomer();
        }],
        sports: ['SportsFactory', 'customer', function(SportsFactory, customer){
            return SportsFactory.getSportsWithLeagues(customer);
        }],
        leagues: ['sports', function(sports){
            var leagueProperties;

            // obtain leagueProperties from sports - whatever you do there.

            return leagueProperties;
        }]
    }
});

A little explanation to go with that, when you minify this: 当您将此最小化时,可以使用以下解释:

function (AuthFactory) {
    return AuthFactory.getCustomer();
}

You get something like this: 您得到的是这样的:

function (_1) {
    return _1.getCustomer();
}

Now it will try to inject _1 which is not defined so the code will fail. 现在它将尝试注入未定义的_1 ,因此代码将失败。 Now when you minify this: 现在,当您缩小此大小时:

['AuthFactory', function(AuthFactory){
    return AuthFactory.getCustomer();
}]

You'll get this: 您将获得:

['AuthFactory', function(_1){
    return _1.getCustomer();
}]

And that will keep working because now _1 is assigned to AuthFactory because angular injects the first parameter in the function with the first string in the array. 这将继续工作,因为现在_1已分配给AuthFactory因为angular将函数中的第一个参数与数组中的第一个字符串一起注入。

Reference: https://docs.angularjs.org/guide/di (see: inline array notation) 参考: https : //docs.angularjs.org/guide/di (请参阅:内联数组表示法)

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

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