Je construis une directive qui prend la forme d'une carte. Lorsque je charge le modèle de carte, je veux m'assurer que la carte est cachée si un utilisateur a déjà caché la carte. Je peux suivre cela via l'attribut request.hide.

Voici ma directive (barebones):

app.directive('request', ['$http', '$timeout', function($http, $timeout) {
    return {
        replace: true,
        templateUrl: '/assets/request.html',
        transclude: false,
        scope: {
            request: '='
        },
        controller: ['$scope', '$http', '$timeout', function($scope, $http, $timeout) {
            // Cool stuff goes in here
        }]
    };
}]);

Et voici mon modèle:

<div>
    <div ng-hide"request.hide" class="card">
        <!-- Cool stuff goes in here -->
    </div>
</div>

Lorsque la page se charge, chaque request possède un attribut hide. En théorie, lorsque j'appelle ma directive, elle devrait être cachée si hide === true. Malheureusement, cela ne semble pas être le cas. Peu importe ce que j'essaie, je ne peux pas cacher ma directive lorsqu'elle est initialisée. J'ai essayé d'utiliser ng-hide="request.hide", ng-show="!request.hide" et ng-if="!request.hide" sur l'élément racine, mais rien ne fonctionne.

Je me suis demandé si ces directives ne fonctionnaient pas sur l'élément racine d'une directive personnalisée, j'ai donc essayé d'envelopper ma directive dans un div supplémentaire et d'utiliser ng-hide, ng-show ou { {X3}} sur le .card div, qui est maintenant un élément enfant, mais cela n'a eu aucun effet non plus.

Il semble que ng-hide ne soit pas du tout évalué ou soit évalué avant que request ne soit défini sur la portée de la directive.

2
Daniel Bonnell 7 mars 2016 à 23:57

4 réponses

Meilleure réponse

Il y a une petite faute de frappe dans le balisage de modèle que vous avez fourni, il manque un signe = après ng-hide. Mais je suppose que ce n'est qu'une faute de frappe pendant que vous écriviez la question.

Sinon, le code de la directive semble correct et devrait fonctionner. Vous devez vérifier l'objet "request" auquel vous liez la directive et vous assurer que la propriété hide est en fait une valeur booléenne et non une chaîne.

Ng-if, ng-show et ng-hide tous les observateurs configurés, donc le problème ne devrait pas être que l'expression soit évaluée avant que l'étendue ne soit remplie.

Juste à des fins de test, essayez de configurer un booléen sur votre portée dans votre contrôleur de directives, et faites le masquer ou si contre cela.

1
Jupo 7 mars 2016 à 21:16

Essayez d'utiliser ngCloak sur le wrapper - div. Il devrait cacher le div et ses enfants tant qu'angular évalue toujours les choses.

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

modifier : En fait non. ngCloak ne fonctionne pas comme je m'en souvenais. Il masque l'élément et tous ses enfants, mais seulement tant qu'il n'a pas été rencontré lors de la phase de compilation - ce qui est trop tôt à mon goût. Vous pouvez cependant écrire votre propre directive de dissimulation.

Voici la source ngCloak's:

var ngCloakDirective = ngDirective({
  compile: function(element, attr) {
    attr.$set('ngCloak', undefined);
    element.removeClass('ng-cloak');
  }
});

Vous auriez besoin d'imiter son comportement dans la phase pré / post-liaison.

0
JanS 7 mars 2016 à 21:24

J'ai finalement trouvé une solution à mon problème, même si j'aimerais toujours savoir ce qui a causé le problème et la meilleure façon de le résoudre.

J'avais une théorie selon laquelle ng-show / ng-hide / ng-if n'étaient pas en cours d'évaluation lorsque ma directive a été compilée, j'ai donc décidé d'utiliser ng-hide="hide" sur l'élément racine de ma directive comme auparavant, mais dans mon contrôleur, plutôt que de définir immédiatement $scope.hide = $scope.request.hide, j'ai décidé de déplacer cela dans un bloc $timeout avec un retard de 10 ms, comme ceci:

$timeout(function() {
    $scope.hide = $scope.request.hide;
}, 10)

Cela déclenche un cycle de résumé une fois la directive compilée, entraînant une réévaluation de ng-hide. Le délai est suffisamment long pour que la directive se compile mais suffisamment court pour être imperceptible pour l'utilisateur.

-1
Daniel Bonnell 9 mars 2016 à 15:56

Ng-show peut être peu fiable.

<div>
    <div ng-show"!!request.hide" class="card">
        <!-- Cool stuff goes in here -->
    </div>
</div>
0
Thomas Bormans 10 mars 2016 à 12:32