javascript 未检测到引导程序折叠事件 hidden.bs.collapse

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26556880/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 06:08:47  来源:igfitidea点击:

bootstrap collapse event hidden.bs.collapse not being detected

javascriptjqueryangularjstwitter-bootstrap-3

提问by André Marcondes Teixeira

I have an angular application that uses bootstrap collapse element. I've created a directive called accordion-list that host the collapsible elements. Then, to listen to the events, i've used jquery event delegation. For some reason, my application can't detect when the bootstrap fires the hidden.bs.collapseevent. Here is my code:

我有一个使用 bootstrap 折叠元素的角度应用程序。我创建了一个名为 Accordion-list 的指令,用于托管可折叠元素。然后,为了监听事件,我使用了 jquery 事件委托。出于某种原因,我的应用程序无法检测引导程序何时触发hidden.bs.collapse事件。这是我的代码:

//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 can help me. Thanks in advance. :)

帮助你们可以帮助我。提前致谢。:)

EDIT

编辑

Here's my files:

这是我的文件:

index.html:

索引.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

部分/手风琴.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:

/* 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:

/* 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:

模拟/lista_inscricao.json:

{
    "Sucesso": true
    ,
    "Mensagem": ""
    ,
    "Dados": {
        "Secretaria": "Secretaria de Educa??o ABC"
        ,
        "Escolas": [
            {
                "Nome": "Escola 1"
                ,
                "QtdProfessores": 12
                ,
                "Series": [
                    {
                        "Nome": "1o Ano Ensino Médio"
                        ,
                        "Turmas": [
                            {
                                "Nome": "A"
                                ,
                                "QtdAlunos": 30
                                ,
                                "QtdTestesA3": 0
                                ,
                                "AlunosPCD": "27,29"
                            }
                            , {
                                "Nome": "B"
                                ,
                                "QtdAlunos": 28
                                ,
                                "QtdTestesA3": 2
                                ,
                                "AlunosPCD": ""
                            }
                        ]
                    }
                    ,
                    {
                        "Nome": "2o Ano Ensino Médio"
                        ,
                        "Turmas": [
                            {
                                "Nome": "A"
                                ,
                                "QtdAlunos": 25
                                ,
                                "QtdTestesA3": 1
                                ,
                                "AlunosPCD": "7"
                            }
                        ]
                    }
                ]
            }
            ,
            {
                "Nome": "Escola 2"
                ,
                "QtdProfessores": 10
                ,
                "Series": [
                    {
                        "Nome": "3o 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": ""
                            }
                        ]
                    }
                ]
            }
        ]
    }
}

回答by bhantol

We don't use jquery code in Controllers.

我们不在控制器中使用 jquery 代码。

Controllers are not the right place for DOM manipulation.

控制器不是 DOM 操作的正确位置。

Directives are what you need for DOM manipulation.

指令是 DOM 操作所需要的。

Also in AngularJS we generally don't use jQuery eventing programming style.

同样在 AngularJS 中,我们通常不使用 jQuery 事件编程风格。

Here is approximate plunker of your orignial code. If I understand correctly you re trying to toggle the state of glyphicon state + and - using the code below:-

这是您的原始代码的近似 plunker 。如果我理解正确,您正在尝试使用以下代码切换字形状态 + 和 - 的状态:-

$("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 herefor the solution plunker.

单击此处获取解决方案 plunker。

The solution is all in accordion.html notice ng-modelhowever I hace commented out your jquery code in the controller.

解决方案都在accordion.html 通知中,ng-model但是我已经在控制器中注释掉了您的jquery 代码。

ng-model="collapseState"

this is to hold the state.

这是守邦。

then further notice

然后进一步通知

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

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

这里我们根据 的值选择类collapseState[$index]

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

还要注意 ng-click 基本上切换了 collapseState[$index]

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

So far what we have done is used a model and altered the view by manipulating the model. This is the gist of AngularJS way.

到目前为止,我们所做的是使用模型并通过操作模型来改变视图。这是 AngularJS 方式的要点。

回答by André Marcondes Teixeira

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

现在,我刚刚更改了我的事件侦听器。出于某种原因,jquery 听不到 hidden.bs.collapse。我注意到单击事件不适合这种情况,因为如果单击速度足够快,则可以以关闭的手风琴和减号图标结束。因此,我已将事件侦听器更改为:

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

This is working pretty well. But, as bhantol said, it not quite the angularjs way of doing things. The one with a better solution win the prize xD

这工作得很好。但是,正如 bhantol 所说,它并不是 angularjs 的做事方式。有更好解决方案的人会赢得奖品 xD