Failed to detect bootstrap hidden.bs.collapse lock event

I have an angular app that uses a bootstrap wrapper element. I created a directive called an accordion list that contains replaceable items. Then, to listen for events, I used jquery event delegation. For some reason, my application cannot detect when bootstrap fires the hidden.bs.collapse event. Here is my code:

//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" }; }); })(); 

Help you guys help me. Thanks in advance.:)

EDIT

Here are my files:

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> 

overtones / 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'); }]); })(); 

mock / 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": "" } ] } ] } ] } } 
+5
source share
2 answers

I just changed my event listener. For some reason, jquery cannot hear hidden. I noticed that the click event is not suitable for this case, because if you click fast enough, you can end with the closed accordion and minus icon on it. So, I changed the event listener to:

 $(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(); }); 

It works very well. But, as bhanthol said, this is not an entirely angular way of doing something. Whoever has the best solution wins xD prize

+6
source

We do not use jquery code in controllers.

Controllers are not suitable for manipulating the DOM.

Directives are what you need to manipulate the DOM.

Also in AngularJS we usually do not use the jQuery event programming style.

Here is an approximate plunker of your character code . If I understand correctly, you are trying to switch the state of the glyphicon state + and - using the following code: -

 $("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 }); 

Click here for plunker solution.

The solution is all in the accordion.html ng-model post, however I commented on your jquery code in the controller.

 ng-model="collapseState" 

it is a hold state.

then pay attention

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

here we select a class based on the value of collapseState[$index] .

Also note the ng-click, which basically toggles the value of collapseState[$index]

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

So far, we have used the model and changed the view by manipulating the model. This is the essence of the AngularJS method.

+6
source

Source: https://habr.com/ru/post/1205477/


All Articles