web-dev-qa-db-fra.com

Attendez que la variable scope soit chargée avant de l’utiliser dans la vue dans angular.js

J'ai vu this et this mais il semble y avoir un moyen plus simple.

À mon avis, plusieurs options de menu sont contrôlées par autorisation - c’est-à-dire que tout le monde ne peut pas voir une vue "Tableau de bord". Donc, dans mon option de menu à mon avis, j'ai quelque chose comme:

<li ng-show="validatePermission('Dashboard')">Dashboard</li>

Dans mon contrôleur, une méthode validatePermission est définie. Elle examine les autorisations de l'utilisateur actuel. Par exemple:

  $scope.validatePermission = function(objectName) {
    if $scope.allPermissions......

Également dans mon contrôleur, je charge ces autorisations via un appel $ http:

  $http.get('permissions/' + userid + '.json').success(function(data) {  
    $scope.allPermissions = data;....

Le problème est que $ scope.allPermissions n'est pas chargé avant que la vue appelle l'appel à validatePermission. Comment puis-je attendre que toutes les autorisations soient chargées avant le rendu de la vue?

31
Arthur Frankel

Demandez à la fonction validatedPermission de renvoyer false lorsque allPermissions n'a pas été chargé. De cette façon, l'élément avec votre ng-show ne sera pas affiché tant que allPermissions n'aura pas été chargé.

Sinon, mettez un ng-show="allPermissions" sur le <ul> ou <ol>.

10
JoeG

Tu demandes:

Comment puis-je attendre que toutes les autorisations soient chargées avant le rendu de la vue?

Pour empêcher le rendu de la vue entière, vous devez utiliser resol. Cependant, vous n’êtes pas obligé d’utiliser la bibliothèque de promesses, puisque $ http renvoie une promesse:

var app = angular.module('app');

app.config(function ($routeProvider) { 
  $routeProvider
    .when('/', {
        templateUrl : 'template.html',
        controller : 'MyCtrl',
        resolve : MyCtrl.resolve
  });
});

function MyCtrl ($scope, myHttpResponse) {
   // controller logic
}

MyCtrl.resolve = {
  myHttpResponse : function($http) {
    return $http({
        method: 'GET',
        url: 'http://example.com'
    })
    .success(function(data, status) {
        // Probably no need to do anything here.
    })
    .error(function(data, status){
        // Maybe add an error message to a service here.
        // In this case your $http promise was rejected automatically and the view won't render.
    });
  }
}

Mais si vous voulez simplement masquer le tableau de bord <li>, faites comme Joe Gauterin l’a suggéré. Voici un très simple exemple plunkr si vous en avez besoin.

21
Rick Jolly

Vous pouvez également spécifier sur votre routecontroller un objet de résolution qui attendra que cet objet soit résolu avant de rendre cette route.

De la angular docs angulaires: https://docs.angularjs.org/api/ngRoute/provider/$routeProvider

resolve - {Object. =} - Une mappe facultative de dépendances à injecter dans le contrôleur. Si l'une de ces dépendances est une promesse, elle sera résolue et convertie en une valeur avant que le contrôleur ne soit instancié et que l'événement $ routeChangeSuccess ne soit déclenché. L'objet de carte est:

key - {string}: nom d'une dépendance à injecter dans le contrôleur. factory - {string | function}: Si string est un alias pour un service. Sinon, si function, alors il est injecté et la valeur de retour est traitée comme une dépendance. Si le résultat est une promesse, il est résolu avant que sa valeur ne soit injectée dans le contrôleur.

Une référence de groupe Google également: https://groups.google.com/forum/#!topic/angular/QtO8QoxSjYw

6
lucuma

J'ai rencontré une situation similaire, vous voudrez peut-être aussi jeter un coup d'œil sur

http://docs.angularjs.org/api/ng/directive/ngCloak

si vous voyez toujours un effet de "scintillement".

Selon la documentation angularjs:

La directive ngCloak est utilisée pour éviter que le modèle html Angular html) soit brièvement affiché par le navigateur dans son format brut (non compilé) pendant le chargement de votre application. Cette directive permet d'éviter l'effet de scintillement indésirable causé par par l'affichage du modèle html.

4
NatraxYN

Envelopper le code dans ng-if a résolu le problème pour moi:

<div ng-if="dependentObject">
  <!-- code for dependentObject goes here -->
</div>
2
WiredIn