2014-10-24 13 views
5

Mam aplikację kątową, która używa elementu zwijania bootstrap. Stworzyłem dyrektywę zwaną listą akordeonową, na której znajdują się składane elementy. Następnie, aby posłuchać wydarzeń, użyłem delegacji zdarzeń jquery. Z jakiegoś powodu moja aplikacja nie może wykryć, kiedy bootstrap uruchomi zdarzenie hidden.bs.collapse. Oto mój kod:Zdarzenie collapse zdarzenia bootstrap hidden.bs.collapse nie jest wykrywane

//app.js 
    'use strict'; 

(function() { 
    var provasNaoIdentificadas = angular.module("provasNaoIdentificadas", [ 
     'restClient' 
    ]); 

    provasNaoIdentificadas.controller("accordionCtrl", ["$scope", "ListaInscricao", function($scope, ListaInscricao){ 
     $scope.inscricao = { 
      "Secretaria": "" 
     }; 

     $("accordion-list").on("hidden.bs.collapse shown.bs.collapse", ".collapse", function (event) { 
      if ($(this).hasClass("in")) { 
       $(this).prev().find(".glyphicon").removeClass("glyphicon-plus glyphicon-minus").addClass("glyphicon-minus"); 
       $(this).prev().find("span.pull-right.text-muted").removeClass("expandir fechar").addClass("fechar"); 
      } else { 
       $(this).prev().find(".glyphicon").removeClass("glyphicon-plus glyphicon-minus").addClass("glyphicon-plus"); 
       $(this).prev().find("span.pull-right.text-muted").removeClass("expandir fechar").addClass("expandir"); 
      } 

      console.log(1, this, event); // i have detected the problem by interpreting 
     }); 

     ListaInscricao.get({"id": 1}, function(data){ 
      if (data.Sucesso) { 
       $scope.inscricao = data.Dados; 
      } else { 
       // toastr 
      } 
     }); 
    }]); 

    provasNaoIdentificadas.directive('accordionList', function() { 
     return { 
      "restrict": "E", 
      "templateUrl": "partials/accordion.html" 
     }; 
    }); 
})(); 

Pomóżcie chłopaki, mogą mi pomóc. Z góry dziękuję. :)

EDIT

Oto moje pliki:

index.html:

<!-- index.html --> 
<!DOCTYPE html> 
<html ng-app="provasNaoIdentificadas"> 
    <head> 
     <title>Hábile: Inscrição De Escolas Públicas Para Provas Não Identificadas</title> 
     <meta charset="UTF-8" /> 
     <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" /> 
     <link rel="stylesheet" href="css/vendor/bootstrap.min.css" /> 
     <script src="js/vendor/jquery-1.11.1.min.js"></script> 
     <script src="js/vendor/bootstrap.min.js"></script> 
     <script src="js/vendor/angular.min.js"></script> 
     <script src="js/vendor/angular-resource.min.js"></script> 
     <script src="js/app.js"></script> 
     <script src="js/rest-client.js"></script> 
     <style> 
      .panel-heading { 
       cursor: pointer; 
      } 

      .panel-heading .panel-title span.pull-right.text-muted { 
       font-size: 10px; 
      } 

      .panel-heading .panel-title span.pull-right.text-muted.expandir:before { 
       content: "clique para expandir"; 
      } 

      .panel-heading .panel-title span.pull-right.text-muted.fechar:before { 
       content: "clique para fechar"; 
      } 
     </style> 
    </head> 
    <body> 
     <div class="container"> 
      <div class="well text-justify"> 
       <h3>Formul&aacute;rio de Inscri&ccedil;&atilde;o H&aacute;bile 2014</h3> 
      </div> 
      <div ng-controller="accordionCtrl"> 
       <h2 id="nomeSecretaria">{{ inscricao.Secretaria }}</h2> 
       <accordion-list></accordion-list> 
      </div> 
      <div class="text-center"> 
       <button type="button" class="btn btn-lg btn-primary">Salvar Inscrição</button> 
       <button type="button" class="btn btn-lg btn-warning">Finalizar Inscrição</button> 
      </div> 
     </div> 
    </body> 
</html> 

partials/accordion.html

<!-- partials/accordion.html --> 
<div class="panel-group" id="accordion_escolas"> 
    <div class="panel panel-default" ng-repeat="escola in inscricao.Escolas"> 
     <div class="panel-heading" data-toggle="collapse" data-target="#escola{{ $index }}" data-parent="#accordion_escolas"> 
      <div class="panel-title"> 
       <span class="glyphicon glyphicon-plus"></span> 
       {{ escola.Nome }} <span class="text-muted">x alunos inscritos</span> 
       <span class="pull-right text-muted expandir"></span> 
      </div> 
     </div> 
     <div id="escola{{ $index }}" class="panel-collapse collapse"> 
      <div class="panel-body"> 
       <p> 
        <label for="qtdProfessoresEscola{{ $index }}">Qtd. Professores</label><br /> 
        <input class="form-control" type="text" id="qtdProfessoresEscola{{ $index }}}}" value="{{ escola.QtdProfessores }}" /> 
       </p> 
       <div class="panel-group" id="accordion_escola{{ $index }}"> 
        <div class="panel panel-default" ng-repeat="serie in escola.Series"> 
         <div class="panel-heading" data-toggle="collapse" data-target="#turma_{{ $index }}_escola{{ $parent.$index }}" data-parent="#accordion_escola{{ $parent.$index }}"> 
          <div class="panel-title"> 
           <span class="glyphicon glyphicon-plus"></span> 
           {{ serie.Nome }} <span class="text-muted">y alunos inscritos</span> 
           <span class="pull-right text-muted expandir"></span> 
          </div> 
         </div> 
         <div id="turma_{{ $index }}_escola{{ $parent.$index }}" class="panel-collapse collapse"> 
          <div class="panel-body"> 
           <table class="table table-hover table-condensed table-bordered"> 
            <thead> 
             <tr> 
              <th>Turma</th> 
              <th>Qtd Alunos</th> 
              <th>Qtd Testes A3</th> 
              <th>Alunos PCD</th> 
              <th></th> 
             </tr> 
            </thead> 
            <tbody> 
             <tr ng-repeat="turma in serie.Turmas"> 
              <td>{{ turma.Nome }}</td> 
              <td><input class="form-control" type="text" value="{{ turma.QtdAlunos }}" /></td> 
              <td><input class="form-control" type="text" value="{{ turma.QtdTestesA3 }}" /></td> 
              <td><input class="form-control" type="text" value="{{ turma.AlunosPCD }}" /></td> 
              <td><button class="btn btn-primary btn-sm" type="button">Excluir Turma</button></td> 
             </tr> 
            </tbody> 
           </table> 
           <p> 
            <button class="btn btn-primary" type="button">Adicionar Turma</button> 
           </p> 
          </div> 
         </div> 
        </div> 
       </div> 
      </div> 
     </div> 
    </div> 
</div> 

js/app.js:

/* js/app.js */ 
'use strict'; 

(function() { 
    var provasNaoIdentificadas = angular.module("provasNaoIdentificadas", [ 
     'restClient' 
    ]); 

    provasNaoIdentificadas.controller("accordionCtrl", ["$scope", "ListaInscricao", function($scope, ListaInscricao){ 
     $scope.inscricao = { 
      "Secretaria": "" 
     }; 

     $("accordion-list").on("hidden.bs.collapse shown.bs.collapse", ".collapse", function (event) { 
      if ($(this).hasClass("in")) { 
       $(this).prev().find(".glyphicon").removeClass("glyphicon-plus glyphicon-minus").addClass("glyphicon-minus"); 
       $(this).prev().find("span.pull-right.text-muted").removeClass("expandir fechar").addClass("fechar"); 
      } else { 
       $(this).prev().find(".glyphicon").removeClass("glyphicon-plus glyphicon-minus").addClass("glyphicon-plus"); 
       $(this).prev().find("span.pull-right.text-muted").removeClass("expandir fechar").addClass("expandir"); 
      } 

      console.log(1, this, event); 
     }); 

     ListaInscricao.get({"id": 1}, function(data){ 
      if (data.Sucesso) { 
       $scope.inscricao = data.Dados; 
      } else { 
       // toastr 
      } 
     }); 
    }]); 

    provasNaoIdentificadas.directive('accordionList', function() { 
     return { 
      "restrict": "E", 
      "templateUrl": "partials/accordion.html" 
     }; 
    }); 
})(); 

js/Rest-client.js:

/* js/rest-client.js */ 
'use strict'; 

(function(){ 
    var restClient = angular.module('restClient', ['ngResource']); 

    restClient.factory('ListaInscricao', ['$resource', function ($resource) { 
     return $resource('mock/lista_inscricao.json'); 
    }]); 
})(); 

makiety/lista_inscricao.json:

{ 
    "Sucesso": true 
    , 
    "Mensagem": "" 
    , 
    "Dados": { 
     "Secretaria": "Secretaria de Educação ABC" 
     , 
     "Escolas": [ 
      { 
       "Nome": "Escola 1" 
       , 
       "QtdProfessores": 12 
       , 
       "Series": [ 
        { 
         "Nome": "1º Ano Ensino Médio" 
         , 
         "Turmas": [ 
          { 
           "Nome": "A" 
           , 
           "QtdAlunos": 30 
           , 
           "QtdTestesA3": 0 
           , 
           "AlunosPCD": "27,29" 
          } 
          , { 
           "Nome": "B" 
           , 
           "QtdAlunos": 28 
           , 
           "QtdTestesA3": 2 
           , 
           "AlunosPCD": "" 
          } 
         ] 
        } 
        , 
        { 
         "Nome": "2º Ano Ensino Médio" 
         , 
         "Turmas": [ 
          { 
           "Nome": "A" 
           , 
           "QtdAlunos": 25 
           , 
           "QtdTestesA3": 1 
           , 
           "AlunosPCD": "7" 
          } 
         ] 
        } 
       ] 
      } 
      , 
      { 
       "Nome": "Escola 2" 
       , 
       "QtdProfessores": 10 
       , 
       "Series": [ 
        { 
         "Nome": "3º Ano Ensino Médio" 
         , 
         "Turmas": [ 
          { 
           "Nome": "A" 
           , 
           "QtdAlunos": 30 
           , 
           "QtdTestesA3": 0 
           , 
           "AlunosPCD": "15,27" 
          } 
          , { 
           "Nome": "B" 
           , 
           "QtdAlunos": 26 
           , 
           "QtdTestesA3": 0 
           , 
           "AlunosPCD": "" 
          } 
          , { 
           "Nome": "C" 
           , 
           "QtdAlunos": 25 
           , 
           "QtdTestesA3": 0 
           , 
           "AlunosPCD": "" 
          } 
         ] 
        } 
       ] 
      } 
     ] 
    } 
} 
+0

Czy zwija się na stronie? Jesteś pewien, że wydarzenie zostało zwolnione? –

+0

jest zwijany, ale zdarzenie nie jest rejestrowane w konsoli i nie zmienia ikony zwijanej po zamknięciu akordeonu –

+0

Myślę, że twój problem jest w kodzie HTML. Czy możesz to opublikować lub zrobić skrzypce? –

Odpowiedz

6

jak na razie, właśnie zmieniłem mój detektor zdarzeń. Z jakiegoś powodu jquery nie może usłyszeć hidden.blscollapse. Zauważyłem, że zdarzenie click jest nieodpowiednie dla tego przypadku, ponieważ jeśli klikniesz wystarczająco szybko, możesz zakończyć z zamkniętym akordeonem i ikoną minusa. Tak więc zmieniłem odbiornik zdarzeń na:

$(document).on("hide.bs.collapse show.bs.collapse", ".collapse", function (event) { 
    $(this).prev().find(".glyphicon").toggleClass("glyphicon-plus glyphicon-minus"); 
    $(this).prev().find("span.pull-right.text-muted").toggleClass("expandir fechar"); 
    event.stopPropagation(); 
}); 

Działa to całkiem dobrze. Ale, jak powiedział bhantol, nie jest to całkiem sposób na zrobienie rzeczy. Ten z lepszym rozwiązaniem wygrywa nagrodę xD

+0

Czy to pytanie zapewnia czysty sposób CSS robienia tego, co próbujesz zrobić? http://stackoverflow.com/a/18568997/1745738 – johnsnails

6

nie używamy kodu jQuery w kontrolerów.

Sterowniki nie są właściwym miejscem do manipulacji DOM.

Dyrektywy są potrzebne do manipulacji DOM.

Również w AngularJS generalnie nie używamy stylu programowania w stylu jQuery.

Oto przybliżony plunker twojego orignial code. Jeśli dobrze rozumiem, ponownie próbuje przełączyć stan państwa glyphicon + i - korzystając z poniższego kodu: -

$("accordion-list").on("hidden.bs.collapse shown.bs.collapse", ".collapse", function (event) { 
    if ($(this).hasClass("in")) { 
     (this).prev().find(".glyphicon").removeClass("glyphicon-plus glyphicon-minus").addClass("glyphicon-minus"); 
     $(this).prev().find("span.pull-right.text-muted").removeClass("expandir fechar").addClass("fechar"); 
    } else { 
     $(this).prev().find(".glyphicon").removeClass("glyphicon-plus glyphicon-minus").addClass("glyphicon-plus"); 
     $(this).prev().find("span.pull-right.text-muted").removeClass("expandir fechar").addClass("expandir"); 
    } 

    console.log(1, this, event); // i have detected the problem by interpreting 
}); 

Kliknij here dla plunker rozwiązania.

Rozwiązaniem jest wszystko w accordion.html zawiadomieniu ng-model jednak I Hace skomentował swój kod jquery w kontrolerze.

ng-model="collapseState" 

służy do utrzymywania stanu.

następnie odwołania

<span class="glyphicon" 
    ng-class="collapseState[$index] ? 'glyphicon-minus' : 'glyphicon-plus'"> 
</span> 

tutaj możemy wybrać klasę w oparciu o wartości collapseState[$index].

zauważyć także ng-click, które w zasadzie przełącza wartość collapseState[$index]

ng-click="collapseState[$index]= !collapseState[$index]" 

tej pory, co zrobiliśmy jest używany model i zmienił pogląd manipulując model. To jest sedno metody AngularJS.

+0

: D dziękuję bardzo za uwagę. –

+0

Stwierdziłem, że zdarzenie click nie jest odpowiednie dla tego przypadku, ponieważ jeśli klikniesz wystarczająco szybko, ikona zakończy się znakiem minus, gdy zamykany jest zamknięty. –

+0

Nie mogłem znaleźć sposobu na kanciaste słuchanie zdarzeń niestandardowych, to jest prawdziwy problem. Potem zmusiłem się do używania manipulacji DOMem JQuery. –

Powiązane problemy