【问题标题】:Why does adding AngularJS break Bootstrap template?为什么添加 AngularJS 会破坏 Bootstrap 模板?
【发布时间】:2014-12-02 14:25:55
【问题描述】:

为什么将 AngularJS 添加到页面会破坏它?我该怎么做才能让它正常运行?控件停止渲染。菜单停止扩展。

我正在尝试将现有 Bootstrap 主题的 index.html 页面划分为部分/模板。不幸的是,一旦我将 HTML 从 index.html 中移出,该分页符上的控件就会中断。

我使用的主题是来自 WrapBootstrap.com 的 KingAdmin v1.3:https://wrapboo...

我要添加的唯一标记是...

ng-app="app"

<div ng-include="'shell.html'"></div>

<script src="assets/thirdparty/angular/1.2.26/angular.js"></script>

<script src="assets/app/app.js"></script>

shell.html 仅包含最初在索引中的正文部分...

无角度:

带角度:

INDEX.HTML:

<head>
    <title>Dashboard | KingAdmin - Admin Dashboard</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <meta name="description" content="KingAdmin - Bootstrap Admin Dashboard Theme">
    <meta name="author" content="The Develovers">

    <!-- CSS -->
    <link href="assets/css/bootstrap.min.css" rel="stylesheet" type="text/css" media="screen">
    <link href="assets/css/font-awesome.min.css" rel="stylesheet" type="text/css" media="screen">
    <link href="assets/css/main.css" rel="stylesheet" type="text/css" media="screen">

    <!--[if lte IE 9]>
            <link href="assets/css/main-ie.css" rel="stylesheet" type="text/css" media="screen" />
            <link href="assets/css/main-ie-part2.css" rel="stylesheet" type="text/css" media="screen" />
    <![endif]-->

    <!-- Fav and touch icons -->
    <link rel="apple-touch-icon-precomposed" sizes="144x144" href="assets/ico/kingadmin-favicon144x144.png">
    <link rel="apple-touch-icon-precomposed" sizes="114x114" href="assets/ico/kingadmin-favicon114x114.png">
    <link rel="apple-touch-icon-precomposed" sizes="72x72" href="assets/ico/kingadmin-favicon72x72.png">
    <link rel="apple-touch-icon-precomposed" sizes="57x57" href="assets/ico/kingadmin-favicon57x57.png">
    <link rel="shortcut icon" href="assets/ico/favicon.png">

</head>

<body class="dashboard">

    <div ng-include="'shell.html'"></div>

    <!-- Javascript -->
    <script src="assets/js/jquery/jquery-2.1.0.min.js"></script>
    <script src="assets/js/bootstrap/bootstrap.js"></script>
    <script src="assets/js/plugins/modernizr/modernizr.js"></script>
    <script src="assets/js/plugins/bootstrap-tour/bootstrap-tour.custom.js"></script>
    <script src="assets/js/king-common.js"></script>

    <script src="assets/js/plugins/stat/jquery.easypiechart.min.js"></script>
    <script src="assets/js/plugins/raphael/raphael-2.1.0.min.js"></script>
    <script src="assets/js/plugins/stat/flot/jquery.flot.min.js"></script>
    <script src="assets/js/plugins/stat/flot/jquery.flot.resize.min.js"></script>
    <script src="assets/js/plugins/stat/flot/jquery.flot.time.min.js"></script>
    <script src="assets/js/plugins/stat/flot/jquery.flot.pie.min.js"></script>
    <script src="assets/js/plugins/stat/flot/jquery.flot.tooltip.min.js"></script>
    <script src="assets/js/plugins/jquery-sparkline/jquery.sparkline.min.js"></script>
    <script src="assets/js/plugins/datatable/jquery.dataTables.min.js"></script>
    <script src="assets/js/plugins/datatable/dataTables.bootstrap.js"></script>
    <script src="assets/js/plugins/jquery-mapael/jquery.mapael.js"></script>
    <script src="assets/js/plugins/raphael/maps/usa_states.js"></script>
    <script src="assets/js/king-chart-stat.js"></script>
    <script src="assets/js/king-table.js"></script>
    <script src="assets/js/king-components.js"></script>

    <script src="assets/thirdparty/angular/1.2.26/angular.js"></script>

    <script src="assets/app/app.js"></script>

</body>
</html>

2014 年 11 月 25 日更新
我已经确认这不是我。我有一个朋友尝试使用 ng-include 标记将模板中的单个页面转换为 Angular 部分,并将其设置在适当的 Node.JS 服务器后面。他也有同样的结果。一旦 Angular 呈现第一页,大量的功能就会中断。各处的展开/折叠逻辑停止工作。大多数控件都会正确停止渲染。

注意
有人提到这个问题可能是由于使用了 ng-include 标记和部分文件,而部分文件没有控制器。侧边栏、顶部栏、面包屑都通过 ng-include 作为静态 HTML / Jade 文件包含在内。一个路由在主体的控制器中通过,但是这个区域也存在问题。

这里是开发者网站上模板的链接:

KingAdmin Dashboard Theme

这是它目前的样子:

从 index.html 页面快速查看修改:

【问题讨论】:

  • 控制台有错误吗?
  • 唯一的错误是 jquery 映射文件。该模板不包括所有的 jquery 文件。但是,我添加了一个包含升级后的 jQuery 和所有相关文件的文件夹,并且错误消失了。这并没有改变上述结果。
  • 对于 glyphicons 右填充似乎与您的 html 压缩或模板引擎有关,它删除了标签之间的间距。其余的似乎 angular 没有运行
  • 您的 html 中是否有 ng-app 指令,或者您是否从 js 手动引导 Angular?
  • 简单的答案是切换到angular-ui.github.io/bootstrap,而不是使用jQuery-specific bootstrap JavaScript。

标签: angularjs jquery-ui twitter-bootstrap-3


【解决方案1】:

部分解决:
不确定这是否会被视为黑客攻击。对 jQuery 和 Angular 有更多了解的人可以/应该插话告诉你这是否安全。

仍未解决:
这似乎在第一次加载页面时起作用。如果您离开页面并再次返回(例如,使用后退按钮),它将不起作用。我相信这是由于 Angular 注入正文而不是重新渲染整个页面......或脚本而发生的。在每个使用 jQuery 的模板中可能可以做一些事情(以某种方式重新初始化等)。 似乎有大量的问题/示例讨论 DOM、jQuery 的类似问题,并使用超时来纠正它们:

AngularJS: How can I run a directive after the dom has finished rendering?

整个修复都在您的公共资源脚本、king-common.js 等中。它们每个都有几个渲染函数,似乎是预先调用的,但 DOM 仍在渲染中。

例子:

$(document).ready(function(){
    $('.main-menu .js-sub-menu-toggle').click( function(e){
    [snip]
    $li.find('.sub-menu').slideToggle(300);
});

通过将这些操作中的每一个包装在 setTimout 中,您可以将渲染推迟到 DOM 被修改之后:

$(document).ready(function(){
    setTimeout(function(){
        $('.main-menu .js-sub-menu-toggle').click( function(e){
        [snip]
        $li.find('.sub-menu').slideToggle(300);
    },1000);
);

这些已移至您的 scripts.jade / scripts.html 文件的尾部。最初这样做是为了延迟这些方法的触发,因此这可能是不必要的。尽管如此,这仍然是我们获得功能模板的一部分。

【讨论】:

  • 这是个坏主意,因为在调用超时 1 秒后 DOM 可能不会被渲染
【解决方案2】:

您的问题是 Bootstrap 没有在您的页面上监视 Angular 为您编译的新创建的元素。您可以创建指令来调用 Bootstrap jQuery 方法,将 Bootstrap 绑定添加到您的元素,例如 ($('.dropdown').dropdown())。

有一个很棒的 AngularJS 库可以替代 bootstrap.js 的角度不可知重写,它可能会为您解决这个问题:http://angular-ui.github.io/bootstrap/

为了快速破解,如果您希望所有带有 .dropdown 类的元素都使用 Bootstrap 下拉菜单,您可以创建这样的指令。

angular.module('app')

        // Directives: https://docs.angularjs.org/guide/directive
       .directive('dropdown', [

        // Use window dependency
        '$window',

        // Returns a directive
        function ($window) {

            return {
                // Restrict to attribute, or class name so can be used like so:
                //
                // <a class="dropdown btn btn-primary">Dropdown button</a>
                // or
                // <a dropdown class="btn btn-primary">Dropdown button</a>
                restrict: 'AC',

                link: {
                    post: [

                        // This dependency gives you the element with
                        // the directive wrapped as a jQuery object
                        '$element',

                        function ($element) {
                            $element.dropdown();
                        }
                    ]
                }
            };

        })

【讨论】:

    【解决方案3】:

    我认为您应该重新考虑您的依赖关系。您的 UI 中损坏的元素似乎需要 jquery,例如:jquery.easypiechart.min.js

    https://docs.angularjs.org/misc/faq,您可以阅读:

    Angular 是否使用 jQuery 库?是的,Angular 可以使用 jQuery,如果 当应用程序被引导时,它会出现在您的应用程序中。 如果 jQuery 不在您的脚本路径中,Angular 会退回到 它自己实现了我们称之为 jQLite 的 jQuery 子集。

    Angular 1.3 仅支持 jQuery 2.1 或更高版本。 jQuery 1.7 和更新版本 可能与 Angular 一起正常工作,但我们不保证这一点。

    注意,Angular 需要 jQuery 2.1 或更高版本,而 Bootstrap 需要 jQuery 的最新 1.1.x 版本(由于 jQuery 2 不支持 IE8,Bootstrap 不支持 jQuery 2+)。

    阅读完以上内容,你还应该阅读:

    【讨论】:

      猜你喜欢
      • 2017-02-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-22
      • 1970-01-01
      • 2018-02-08
      • 1970-01-01
      相关资源
      最近更新 更多