Pergunta

Estou criando um aplicativo ASP.net MVC e exibindo ng-grid com uma coluna que possui link como conteúdo da célula.

Veja como consegui isso.
Controlador (grade ng):

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

Diretiva:

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

Filtro:

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

Funciona bem, mas quando clico no Rules link Não consigo exibir a caixa de diálogo.

Tentei abrir a caixa de diálogo clicando em um botão separadamente e funcionou.Preciso de ajuda!

Foi útil?

Solução

Dado que a sua directiva tem um escopo isolado (ver Isolando o escopo de uma diretiva), o que posso dizer porque sua declaração contém scope: {...}, a diretiva limitará os itens do escopo apenas ao que sua diretiva define.

É possível que as diretivas herdem itens de um escopo pai, ou até mesmo usem o mesmo escopo do pai, mas isso não acontecerá neste caso.

Quando você tem um escopo isolado, a única maneira de definir itens nesse escopo é colocá-los em um controlador, link função, ou defini-los como um opção de escopo dentro da sua directiva.Agora se getRulesTest() é específico apenas para sua diretiva (não reutilizável fora dela, não definido em um controlador pai, etc.), então apenas defina-o em seu link função (ou controlador da diretiva, se houver, o que fizer sentido):

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

Como você nunca o define dentro do escopo da diretiva em nenhum lugar do seu exemplo, presumo que você o esteja declarando em um controlador pai e esteja pensando que deveria apenas sair do escopo da diretiva e encontrá-lo no escopo pai.Como eu disse acima, isso não vai funcionar.Você pode usar uma opção de escopo que se liga a uma função usando o & sintaxe.Isso permite que sua visão atribua declarativamente uma função do escopo pai para sua diretiva usar quando precisar chamar.

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

Adicionamos a opção de escopo ao seu scope declaração.Agora seu controlador pai adicionaria uma função no escopo a ser vinculada:

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

E a visualização ficaria assim:

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

A outra coisa que pode ser problemática é o que você está fazendo com esta linha no modelo:

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

Você está tentando passar para essa função o resultado da string avaliada de {{freightRules}} (o que não parece muito útil), ou você deseja passá-lo na prática freightRules objeto (o que parece mais provável)?Se sim, basta alterá-lo para:

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

Editar

Aqui está um plunk com um exemplo prático.

Detectei um pequeno erro na minha resposta original sobre como chamar opções de escopo de função.Existem algumas maneiras de chamar funções que você vinculou, dependendo se você tem ou não parâmetros e como deseja que eles correspondam.Esta parte é um pouco confusa.Se você não estiver acompanhando, siga a opção nº 2.

1.Você quer apenas passar o nome da função que deve chamar, com parâmetros determinados ordinalmente.

Digamos que você queira que eles simplesmente declarem (observe que fornecemos apenas o nome das regras, sem parênteses ou nomes de parâmetros):

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

Então sua diretiva deve invocar a função assim (observe que chamamos uma função simples, que gera um invocador que pode ser usado para realmente chamar a função, e então nós o chamamos com os parâmetros reais):

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

2.Você deseja que o invocador passe argumentos nomeados para poder alterar a ordem ou omitir parâmetros.

Isso é melhor ilustrado se você tiver vários parâmetros.Digamos que a diretiva forneça dois parâmetros, paramA e paramB.Você invoca a função em sua diretiva usando um objeto contendo nomes e valores de parâmetros.

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

Então, ao usar a diretiva, sua marcação fica assim:

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

A razão pela qual isso é preferível é na situação em que você deseja reordenar ou omitir um parâmetro na função que está sendo invocada.Digamos doSomethingWithRules só precisa paramB.Agora posso fazer:

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

Eu não poderia ter feito isso com a opção nº 1 acima, porque ela sempre invoca todos os parâmetros ordinalmente.Portanto, a opção 2 é preferível porque dá aos consumidores da sua diretiva mais flexibilidade e evita o incômodo de ter que lembrar a ordem em que os parâmetros são fornecidos à sua função.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top