【问题标题】:Javascript not accessible from inside Angular ui-view无法从 Angular ui-view 内部访问 Javascript
【发布时间】:2015-07-11 19:42:28
【问题描述】:

我有一个带有 Angular ui-view 的主模板 (index.html)。在这个主模板中,我导入了一堆 Javascript 文件。我希望这些文件可用于将在 ui-view 中加载的 html 模板中的内容,但 JS 函数似乎无法访问。

/sample-app/index.html:

<html ng-app="otr">
<head></head>
<body>
    <div ui-view></div>

    <!-- JS imports -->
    <script src="//code.jquery.com/jquery-2.1.3.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>

    <!-- Angular Dependencies -->
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0-rc.1/angular.min.js"></script>
    <script src="https://code.angularjs.org/1.4.0-rc.1/angular-route.min.js"></script>
    <script src="https://code.angularjs.org/1.4.0-rc.1/angular-cookies.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.14/angular-ui-router.min.js"></script>

    <!-- Custom scripts -->
    <script src="/sample-app/js/login.js"></script>

    <!-- Angular app scripts -->
    <script src="app/app.js"></script>
    <script src="app/services/authentication.service.js"></script>
    <script src="app/services/flash.service.js"></script>
    <script src="app/common/cases-model.js"></script>

    <script src="app/home/home.controller.js"></script>
    <script src="app/login/login.controller.js"></script>
    <script src="app/register/register.controller.js"></script>        

</body>
</html>

/sample-app/js/login.js

$(function() {

    $('#login-form-link').click(function(e) {
        $("#login-form").delay(100).fadeIn(100);
        $("#register-form").fadeOut(100);
        $('#register-form-link').removeClass('active');
        $(this).addClass('active');
        e.preventDefault();
    });
    $('#register-form-link').click(function(e) {
        console.log('Inside login.js REGISTER');
        $("#register-form").delay(100).fadeIn(100);
        $("#login-form").fadeOut(100);
        $('#login-form-link').removeClass('active');
        $(this).addClass('active');
        e.preventDefault();
    });

});

/sample-app/app/app.js:

(function () {
    'use strict';

    angular.module('otr', [
        'ngRoute',
        'ngCookies',
        'ui.router',
    ])
        .config(config)
        .run(run);

    function config($stateProvider, $urlRouterProvider, $httpProvider) {

        $stateProvider
            .state('otr', {
                url: '',
                abstract: true
            })
            .state('login', {
                url: '/login',
                controller: 'LoginController as vm',
                templateUrl: 'app/login/login.view.html'
            })
            .state('register', {
                url: '/register',
                controller: 'RegisterController as vm',
                templateUrl: 'app/register/register.view.html'
            })
            .state('home', {
                url: '/',
                controller: 'HomeController as vm',
                templateUrl: 'pages/home2.view.html'
            })
        ;

        $urlRouterProvider.otherwise('/login');
        $httpProvider.defaults.withCredentials = true;
    }

    function run($rootScope, $location, $cookies, $http) {
        // keep user logged in after page refresh
        $rootScope.globals = $cookies.get('globals') || {};

        $rootScope.$on('$locationChangeStart', function (event, next, current) {
            // redirect to login page if not logged in and trying to access a restricted page
            var restrictedPage = $.inArray($location.path(), ['/login', '/register']) === -1;
            var loggedIn = $rootScope.globals.currentUser;
            if (restrictedPage && !loggedIn) {
                $location.path('/login');
            }
        });
    }

})();
  • ui-view 内容加载正常,但没有调用 JS 函数。
  • 如果我将内容直接复制/粘贴到 index.html 中,一切正常
  • 如果我将 JS 导入放在部分模板中,那也可以。

我错过了什么?

【问题讨论】:

  • 您能否发布更多关于您在 app.js 中拥有的内容的详细信息?我可能会假设我不应该对您的代码做出一些假设。
  • 与其编写一堆 jQuery 来制作动画,不如使用 ng-animate。它会让你的生活更轻松,并让你的一些代码不再繁琐。

标签: javascript jquery html angularjs


【解决方案1】:

如果你想访问外部的东西,尝试创建一个控制器,像这样,

<body>
    <div ng-controller="MainCtrl">
      <div ui-view></div>
      <script src="app/app.js"></script>
    </div>
</body>

【讨论】:

  • 如何解决js文件加载问题
【解决方案2】:

没有看到您的项目结构很难确定,但我怀疑您需要使用绝对路径而不是相对路径来引用您的 javascript 文件。

EG:

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

我这样说是因为大多数 AngularJS 项目将它们的视图存储在一个子文件夹中,当模板被加载时,相对路径变得无效,因为它们是相对于 project/index.html 文件的根目录而不是活动视图.

【讨论】:

  • 我刚试过,但没有运气。我试过完整路径和相对路径。两者似乎都不起作用。
  • 您是在本地测试还是从 Web 服务器测试?如果它是本地的,如果浏览器中的 URL 以 file: 开头,您可以判断它是本地的,然后尝试切换回相对路径并确保您的项目的结构使得路径对索引和视图有效。另外,如果你在浏览器中调出开发者控制台,它是否提供了任何线索?
  • 我回到使用相对路径。我在本地服务器上运行它(即localhost:63342/...)。开发者控制台没有抱怨任何事情,也没有给我任何可能出错的线索。如果我给它错误的 JS 文件路径,它会抱怨,所以我知道它找到了文件。
  • 当您将代码放入主文件并且它可以工作时,您是逐字包含所有代码,还是更改其中任何一个。另外,你把它放在哪里?标题还是正文结尾?
【解决方案3】:

您应该使用 ng-app 声明应用名称,然后将控制器与 HTML 中的元素相关联。我建议this tutorial,因为您缺少一些基础知识。

你需要做这样的事情:

<!DOCTYPE html>
<html ng-app="myapp" lang="en">
<head>
    <script type="text/javascript" src="js/app.js"></script>
</head>
<body>
    <div ng-controller="MyCtrl"></div>
</body>
</html>

app.js:

(function () {
    var app = angular.module('myapp', []);
    app.controller("MyCtrl", function($scope){
        $scope.foo = function(){};
        this.foo2 = function(){};
    })
})();

【讨论】:

  • 我已经进一步澄清了这个问题。我应该明确表示我已经指定了 ng-app 并连接了控制器。
【解决方案4】:

大概,您在app.js 的某处有如下声明:

angular.module('MyApp', []);

您需要手动引导您的应用程序。如果您的 html 中有任何 ng-app= 标记,请将其删除 - 确保 app.js 是最后一个脚本,并将以下内容添加到 app.js 的末尾:

angular.element(document).ready(function() {
  angular.bootstrap(document, ['MyApp']);
});

如果您的标记中没有ng-app,那么无论如何您都不会看到任何东西,因为ng-app 是告诉angular 应该在哪里与您的页面集成的关键。在加载所有脚本之前,不应应用 ng-app

但即使你拥有它,它仍然会给你一个错误,即指令未定义。原因是 angular.js 将在加载后立即开始执行。但是您编写的将指令附加到模块的代码还没有机会执行。非常具体地说,这意味着您的应用程序中还没有定义一个名为“ui-view”的指令。

当您将 Angular 代码放入 index.html 时,它似乎可以正常工作的原因是,在实际尝试连接组件之前,Angular 足以等待 DOM 准备好,这意味着任何内联脚本已经得到了执行的机会。

把这个引导技巧放在你的包里,因为你会经常使用它。

【讨论】:

  • OP 已经声明视图加载...那么为什么所有关于ng-app 和引导的解释?如果OP
  • 如果 javascript 不可用,那么它还没有加载——很可能是因为我已经描述的原因。 ui-view 几乎可以肯定是取自 angular-ui-router 的指令,因此它没有与 OP 的代码捆绑在一起。但我非常感谢您对 OP 的关注。
  • 我认为您误读了问题。是的,需要 ui-roter,但是如果它们还没有被包含为依赖项,那么 OP 将如何看到在 ui-view 中呈现的视图?问题在于这些视图内的脚本标签中的 js
  • 感谢您的关注。提交此答案后不久,我向 OP 留言要求澄清和额外的代码示例——以防我做出错误的假设。不是我不相信你的解释,而是我要等待 OP 回复。问题中没有提供足够的信息让我们来回接受教育。 ;-)
  • @MichaelHays 我尝试了这种方法,但它并没有解决我的问题。无论我使用上面的技巧还是保留 ng-app 属性,它的工作原理都是一样的。我在上面添加了更多代码以消除假设。我的问题不是让我的部分模板加载到 中,而是部分模板内的标记无权访问 index.html 中导入的 JS。如果我改为将
【解决方案5】:

我放弃了尝试让 JavaScript 加载和 ui-view 识别它。我最终通过创建一个复制 JavaScript 功能的 Angular 指令解决了这个问题。

指令:

angular.module('otr')
    .directive('loginForm', loginFormDirective)
    .directive('registerForm', registerFormDirective)
;

function loginFormDirective() {
    return function(scope, element, attrs) {

        element.bind('click', function() {
            console.log('element: ', element[0].id);
            console.log('attributes: ', attrs);

            $('#' + attrs.loginForm).delay(100).fadeIn(100);
            $("#register-form").fadeOut(100);
            $('#register-form-link').removeClass('active');
            $('#' + element[0].id).addClass('active');
        })
    }
}

function registerFormDirective() {
    return function(scope, element, attrs) {

        element.bind('click', function() {
            $('#' + attrs.registerForm).delay(100).fadeIn(100);
            $("#login-form").fadeOut(100);
            $('#login-form-link').removeClass('active');
            $('#' + element[0].id).addClass('active');
        })
    }
}

我的视图现在有如下代码sn-p:

<div class="row">
    <div class="col-xs-6">
        <a href="#" class="active" id="login-form-link" login-form="login-form">Login</a>
    </div>
    <div class="col-xs-6">
        <a href="#" id="register-form-link" register-form="register-form">Register</a>
    </div>
</div>

感谢所有花时间阅读我的问题并发布答案的人!

【讨论】:

    【解决方案6】:

    这是一个超级迟到的回应,但我自己也遇到了同样的问题。我已经通过在包含 Angular 和 Angular UI Router 之前包含外部 js 库来解决这个问题。

    就像 OP 一样,我的项目由 index.html 和 ui-view 组成。部分正确加载到 ui-view 中,但外部 js 库不会通过 ui-view 在部分内部生效。如果将部分内容放入 index.html,则一切正常。

    脚本更改自

    <!-- AngularJS -->
    <script type="text/javascript" src="node_modules/angular/angular.min.js"></script>
    <script type="text/javascript" src="node_modules/angular-ui-router/release/angular-ui-router.min.js"></script>
    <script src="dist/components.js" type="text/javascript"></script>
    
    <!-- Custom JS Libries -->
    <script src="dist/js/custom.js" type="text/javascript"></script>  
    

    脚本更改为

    <!-- Custom JS Libries -->
    <script src="dist/js/custom.js" type="text/javascript"></script>
    
    <!-- AngularJS -->
    <script type="text/javascript" src="node_modules/angular/angular.min.js"></script>
    <script type="text/javascript" src="node_modules/angular-ui-router/release/angular-ui-router.min.js"></script>
    <script src="dist/components.js" type="text/javascript"></script> 
    

    最终结果和工作

    <!DOCTYPE html>
    <html dir="ltr" data-config='{"style": "calico"}'>
    <head>
        <link rel="stylesheet" href="dist/all.css">
    </head>
    
    <body ng-app="MyApp">
    
        <div ui-view></div>
    
        <!-- Custom JS Libries -->
        <script src="dist/js/custom.js" type="text/javascript"></script>
    
        <!-- AngularJS -->
        <script type="text/javascript" src="node_modules/angular/angular.min.js"></script>
        <script type="text/javascript" src="node_modules/angular-ui-router/release/angular-ui-router.min.js"></script>
        <script src="dist/components.js" type="text/javascript"></script> 
    
    </body>
    </html>
    

    【讨论】:

      【解决方案7】:

      这就是我解决问题的方法。

      1. 在您的 app.js 中,create 在控制器上,
      2. 将控制器名称添加到您的索引正文中
      3. 将模板js转换为方法。
      4. 然后在您的 app.js 控制器中创建一个范围方法。
      5. 在scope方法中,调用模板js方法
      6. 在 ui-view html 模板或您的仪表板中,使用 ng-init 调用 app.js 控制器的 scope 方法,使用

      下面是工作示例:

      index.html

      <!DOCTYPE html>
      <!--[if lt IE 7]>      <html lang="en" ng-app="zeusWeb" class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
      <!--[if IE 7]>         <html lang="en" ng-app="zeusWeb" class="no-js lt-ie9 lt-ie8"> <![endif]-->
      <!--[if IE 8]>         <html lang="en" ng-app="zeusWeb" class="no-js lt-ie9"> <![endif]-->
      <!--[if gt IE 8]><!--> <html lang="en" ng-app="zeusWeb" class="no-js"> <!--<![endif]-->
      <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title>Screening Manager</title>
        <meta name="keywords" content="education, institution, management, portal,screening,application">
        <meta name="description" content="education, institution, management, portal,screening,application">
        <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
        <meta name="author" content="K-Devs System Solutions">
        <meta name="owner" content="Kazeem Olanipekun">
        <meta name="verified by" content="K-Devs System Solutions">
        <meta name="googlebot" content="noodp">
        <meta name="google" content="translate">
        <meta name="revisit-after" content="1 month">
        <!-- build:css css/main.css-->
        <!-- bower:css -->
        <link rel="stylesheet" href="bower_components/angular-loading-bar/build/loading-bar.css" />
        <link rel="stylesheet" href="bower_components/font-awesome/css/font-awesome.css" />
        <link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.css" />
        <link rel="stylesheet" href="bower_components/bootstrap-daterangepicker/daterangepicker.css" />
        <link rel="stylesheet" href="bower_components/malihu-custom-scrollbar-plugin/jquery.mCustomScrollbar.css" />
        <link rel="stylesheet" href="bower_components/animate.css/animate.css" />
        <link rel="stylesheet" href="bower_components/iCheck/skins/flat/blue.css" />
        <link rel="stylesheet" href="bower_components/nprogress/nprogress.css" />
        <link rel="stylesheet" href="bower_components/bootstrap-progressbar/css/bootstrap-progressbar-3.3.4.css" />
        <link rel="stylesheet" href="bower_components/switchery/dist/switchery.css" />
        <!--endbower-->
        <!--custom:css-->
        <link href="template.css" rel="stylesheet">
        <link rel="stylesheet" href="app.css">
        <!-- endcustom  css-->
        <!-- endbuild -->
        <link rel="shortcut icon" href="images/screening.ico" type='image/x-icon'/>
        <link rel="icon" href="images/screening.ico" type="image/x-icon"/>
          <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
          <!--[if lt IE 9]>
          <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
          <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
          <![endif]-->
      </head>
      <body data-ng-controller="zeusWebCtrl" class="nav-md footer_fixed">
        <!--[if lt IE 7]>
            <p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
        <![endif]-->
      
        <data ui-view ng-cloak></data>
      
        <!-- build:js js/vendors.js-->
        <!-- bower:js -->
        <script src="bower_components/jquery/dist/jquery.js"></script>
        <script src="bower_components/angular/angular.js"></script>
        <script src="bower_components/angular-mocks/angular-mocks.js"></script>
        <script src="bower_components/angular-bootstrap/ui-bootstrap-tpls.js"></script>
        <script src="bower_components/angular-ui-router/release/angular-ui-router.js"></script>
        <script src="bower_components/angular-loading-bar/build/loading-bar.js"></script>
        <script src="bower_components/bootstrap/dist/js/bootstrap.js"></script>
        <script src="bower_components/moment/moment.js"></script>
        <script src="bower_components/bootstrap-daterangepicker/daterangepicker.js"></script>
        <script src="bower_components/jquery-mousewheel/jquery.mousewheel.js"></script>
        <script src="bower_components/malihu-custom-scrollbar-plugin/jquery.mCustomScrollbar.js"></script>
        <script src="bower_components/iCheck/icheck.js"></script>
        <script src="bower_components/nprogress/nprogress.js"></script>
        <script src="bower_components/bootstrap-progressbar/bootstrap-progressbar.js"></script>
        <script src="bower_components/transitionize/dist/transitionize.js"></script>
        <script src="bower_components/fastclick/lib/fastclick.js"></script>
        <script src="bower_components/switchery/dist/switchery.js"></script>
        <!-- endbower -->
        <!-- endbuild -->
      
      
        <!-- build:js js/main.js-->
        <!-- code inclusion-->
        <script src="template.js"></script>
        <script src="scripts/index.js"></script>
        <script src="scripts/dashboard/dashboard.js"></script>
        <script src="app.js"></script>
        <!--end inclusion -->
        <!-- endbuild -->
      
      </body>
      </html>
      

      这里是 app.js

      'use strict';
      // Declare app level module which depends on views, and components
      var zeusWeb=angular.module('zeusWeb', ['ui.router', 'angular-loading-bar','dashboard']);
      zeusWeb.config(['$stateProvider', '$urlRouterProvider','cfpLoadingBarProvider',function ($stateProvider, $urlRouterProvider,cfpLoadingBarProvider) {
      
        $urlRouterProvider.otherwise("/");
        /**
         *   State for the very first page of the app. This is the home page .
         */
        $stateProvider.state('home', {
          url: "/",
          templateUrl: 'views/dashboard/dashboard.html',
          controller: 'dashboardCtrl'
        });
      /*
        $stateProvider.state('dashboard', {
              url:'/dashboard',
              templateUrl: 'views/dashboard/dashboard.html',
              controller: 'dashboardCtrl',
              controllerAs:'vm'
        });*/
      
      /*
        $stateProvider.state('dashboard', {
          views:{
            'body':{
              url:'/embed',
              templateUrl: 'view1/embed.html',
              controller: 'embed',
              controllerAs:'vm'
            }
          }
        });*/
      
      }]);
      zeusWeb.controller('zeusWebCtrl',['$scope',function ($scope) {
        $scope.test = "Testing";
        $scope.appTemplate=function () {
        template();
        };
      
      }]);
      

      这里是嵌入的 ui-view dashboard.html

      <div  class="container body">
          <div class="main_container">
              <!--sidebar-->
              <section  data-ng-include="'views/dashboard/sidebar-nav.html'" data-ng-controller="sideBarCtrl as vm"></section>
              <!--sidebar-->
      
              <!-- top navigation -->
              <section  data-ng-include="'views/dashboard/header.html'"></section>
              <!-- /top navigation -->
      
              <!-- page content -->
              <div class="right_col" role="main" ui-view="body">
                  hey
                <!--  <script>template();</script>-->
              </div>
              <!-- /page content -->
              <!--footer-->
              <section  data-ng-include="'views/dashboard/footer.html'"></section>
              <!--footer-->
          </div>
      </div>
      <div data-ng-init="$parent.appTemplate()"></div>
      

      请注意,如果您有一个基于角色的异步注入侧边栏 html。确保您有一个默认的侧边栏 html 将其放入仪表板,并确保默认侧边栏将在所有其他侧边栏成功加载后最后加载。

      在我的例子中,这是一个侧边栏的示例。

      学校管理 html 侧边栏

      <div  class="menu_section">
          <h3>Live On</h3>
          <ul class="nav side-menu">
              <li><a><i class="fa fa-bug"></i> Additional Pages <span class="fa fa-chevron-down"></span></a>
                  <ul class="nav child_menu">
                      <li><a href="e_commerce.html">E-commerce</a></li>
                      <li><a href="projects.html">Projects</a></li>
                      <li><a href="project_detail.html">Project Detail</a></li>
                      <li><a href="contacts.html">Contacts</a></li>
                      <li><a href="profile.html">Profile</a></li>
                  </ul>
              </li>
              <li><a><i class="fa fa-windows"></i> Extras <span class="fa fa-chevron-down"></span></a>
                  <ul class="nav child_menu">
                      <li><a href="page_403.html">403 Error</a></li>
                      <li><a href="page_404.html">404 Error</a></li>
                      <li><a href="page_500.html">500 Error</a></li>
                      <li><a href="plain_page.html">Plain Page</a></li>
                      <li><a href="login.html">Login Page</a></li>
                      <li><a href="pricing_tables.html">Pricing Tables</a></li>
                  </ul>
              </li>
              <li><a><i class="fa fa-sitemap"></i> Multilevel Menu <span class="fa fa-chevron-down"></span></a>
                  <ul class="nav child_menu">
                      <li><a href="#level1_1">Level One</a>
                      <li><a>Level One<span class="fa fa-chevron-down"></span></a>
                          <ul class="nav child_menu">
                              <li class="sub_menu"><a href="level2.html">Level Two</a>
                              </li>
                              <li><a href="#level2_1">Level Two</a>
                              </li>
                              <li><a href="#level2_2">Level Two</a>
                              </li>
                          </ul>
                      </li>
                      <li><a href="#level1_2">Level One</a>
                      </li>
                  </ul>
              </li>
              <li><a href="javascript:void(0)"><i class="fa fa-laptop"></i> Landing Page <span class="label label-success pull-right">Coming Soon</span></a></li>
          </ul>
      </div>
      

      那么,假设这是用户的最后一个侧边栏,然后你调用默认侧边栏来调用函数

      默认侧边栏 html

      <div data-ng-init="$parent.appTemplate()"></div>`enter code here
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-02-22
        • 2018-12-30
        相关资源
        最近更新 更多