Question

Je crée une application ASP.net MVC et j'affiche ng-grid avec une colonne qui a un lien comme contenu de cellule.

Voici comment j'y suis parvenu.
Contrôleur (ng-grid) :

columnDefs: [
 { field: 'FreightRules', visible: true, 
    cellTemplate: 
     '<div class="rulesDirective" freight-rules="{{row.entity.FreightItemGuid}}">
          </div>', 
    enableCellEdit: false, enableCellSelection: false }]

Directif:

directives.directive('rulesDirective', function () {
    return {
        restrict: 'C',
        replace: true,
        transclude: true,
        scope: { freightRules: '@freightRules' },
        template: '<div ng-switch on="freightRules | areRulesAvailable">' +
                  '<div ng-switch-when = true><a ng-click="getRulesTest(\'{{freightRules}}\')" href="#addFreightRuleModal">Rules</a></div>' +
                  '<div ng-switch-when = false>No Rules</div>' +
                  '<div ng-switch-default class="grid">Error</div>' +
               '</div>'
        }});

Filtre:

filters.filter('areRulesAvailable', function () {
    return function (value) {
        if (value != '00000000-0000-0000-0000-000000000000') {
            result= true;
        }
        else {
            result = false;
        }
        return result;
    };
});

Cela fonctionne bien mais quand je clique sur le Rules lien Je ne parviens pas à afficher la boîte de dialogue.

J'ai essayé d'ouvrir la boîte de dialogue en cliquant sur un bouton séparément et cela a fonctionné.Besoin d'aide!

Était-ce utile?

La solution

Puisque votre directive a un portée isolée (voir Isoler le champ d’application d’une directive), ce que je peux dire car sa déclaration contient scope: {...}, la directive limitera les éléments de la portée à ce que définit votre directive.

Il est possible que les directives héritent des éléments d'une portée parent, ou même utilisent la même portée que le parent, mais ce ne sera pas le cas dans ce cas.

Lorsque vous avez une étendue isolée, la seule façon de définir des éléments sur cette étendue est de les y placer dans un contrôleur, link fonction, ou les définir comme un option de portée dans votre directive.Maintenant si getRulesTest() est spécifique uniquement à votre directive (non réutilisable en dehors de celle-ci, non défini sur un contrôleur parent, etc.), puis définissez-le simplement dans votre link fonction (ou le contrôleur de la directive s'il en a un, selon ce qui a du sens) :

directives.directive('rulesDirective', function () {
    return {
        restrict: 'C',
        replace: true,
        transclude: true,
        scope: { freightRules: '@freightRules' },
        link: function($scope) { // looky here
            $scope.getRulesTest = function() {
                 console.log('check me out');
            };
        },
        template: '<div ng-switch on="freightRules | areRulesAvailable">' +
                  '<div ng-switch-when = true><a ng-click="getRulesTest(freightRules)" href="#addFreightRuleModal">Rules</a></div>' +
                  '<div ng-switch-when = false>No Rules</div>' +
                  '<div ng-switch-default class="grid">Error</div>' +
               '</div>'
        }});

Puisque vous ne le définissez jamais dans la portée de la directive dans votre exemple, je suppose que vous le déclarez sur un contrôleur parent et vous pensez qu'il devrait simplement appeler hors de la portée de la directive et le trouver dans la portée parent.Comme je l'ai dit plus haut, cela ne fonctionnera pas.Vous pouvez utiliser une option de portée qui se lie à une fonction à l'aide du & syntaxe.Cela permet à votre vue d'attribuer de manière déclarative une fonction de la portée parent que votre directive doit utiliser lorsqu'elle doit être appelée.

directives.directive('rulesDirective', function() {
  return {
    restrict: 'C',
    replace: true,
    transclude: true,
    scope: {
      freightRules: '=',
      getRulesTest: '&rulesTest' // <- this guy. the text on the left is what you want the item named on the scope locally. the text on the right, after the & is what the attribute on the element should be called. if you want them to be the same on both sides, simply enter '&'
    },
    template: '<div ng-switch on="freightRules | areRulesAvailable">' +
      '<div ng-switch-when="true"><a ng-click="getRulesTest({rules: freightRules})" href="">Rules</a></div>' +
      '<div ng-switch-when="false">No Rules</div>' +
      '<div ng-switch-default class="grid">Error</div>' +
      '</div>'
  };
})

Nous avons ajouté l'option de portée à votre scope déclaration.Maintenant, votre contrôleur parent ajouterait une fonction sur la portée à laquelle être lié :

.controller('MyCtrl', function($scope) {
   $scope.doSomethingWithRules = function(rules) {
         console.log('sup?');
   };
});

Et la vue ressemblerait à :

<div class="rules-directive" rules-test="doSomethingWithRules(rules)"></div>

L'autre chose qui pourrait poser problème est ce que vous faites avec cette ligne dans le modèle :

ng-click="getRulesTest(\'{{freightRules}}\')"

Essayez-vous de transmettre à cette fonction le résultat de la chaîne évaluée de {{freightRules}} (ce qui ne semble pas très utile), ou souhaitez-vous le transmettre dans le réel freightRules objet (ce qui semble plus probable) ?Si c'est le cas, changez-le simplement par :

ng-click="getRulesTest({rules: freightRules})"

Modifier

Voici un morceau avec un exemple concret.

J'ai détecté une petite erreur dans ma réponse originale sur la façon d'appeler les options de portée de fonction.Il existe plusieurs façons d'appeler les fonctions que vous avez liées, selon que vous avez ou non des paramètres et comment vous souhaitez qu'ils correspondent.Cette partie est un peu déroutante.Si vous ne suivez pas, restez simplement sur l'option n°2.

1.Vous voulez juste passer le nom de la fonction qu'il doit appeler, avec des paramètres déterminés de manière ordinale.

Supposons que vous souhaitiez simplement qu'ils indiquent (notez que nous fournissons uniquement le nom des règles, pas de parenthèses ni de noms de paramètres) :

<div class="rules-directive" ... rules-test="doSomethingWithRules">

Ensuite, votre directive doit invoquer la fonction comme ceci (notez que nous appelons une fonction nue, qui génère un invocateur qui peut être utilisé pour appeler réellement la fonction, et alors nous l'appelons avec les paramètres réels) :

ng-click="getRulesTest()(rules)"

2.Vous souhaitez que l'invocateur transmette des arguments nommés afin que vous puissiez modifier l'ordre ou omettre des paramètres.

Ceci est mieux illustré si vous avez plusieurs paramètres.Disons que la directive fournit deux paramètres, paramA et paramB.Vous invoquez la fonction dans votre directive à l'aide d'un objet contenant les noms et valeurs des paramètres.

ng-click="getRulesTest({paramA: valuesForA, paramB: valuesForB })"

Ensuite, lorsque vous utilisez la directive, votre balisage ressemble à ceci :

<div class="rules-directive" ... rules-test="doSomethingWithRules(paramA, paramB)">

La raison pour laquelle cela est préférable est dans le cas où vous souhaitez réorganiser ou omettre un paramètre dans la fonction invoquée.Disons doSomethingWithRules seulement besoin paramB.Maintenant je peux faire :

<div class="rules-directive" ... rules-test="doSomethingWithRules(paramB)">

Je n'aurais pas pu faire cela avec l'option n°1 ci-dessus, car elle invoque toujours tous les paramètres de manière ordinale.Ainsi, l'option n°2 est préférable car elle donne aux consommateurs de votre directive plus de flexibilité et leur évite d'avoir à se rappeler dans quel ordre les paramètres sont fournis à votre fonction.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top