AngularJS中如何跨文件调用函数?公共头部复用场景
解决AngularJS公共头部组件的toggle功能问题
看起来你在AngularJS里实现公共头部的菜单toggle功能时遇到了几个关键问题,我帮你梳理一下问题点并给出具体的解决方案:
一、当前代码的核心问题
- ng-include与Component的冲突:你在index.html里用
ng-include直接引入了header.html,但同时又在header.js里定义了一个component,这两种方式没有关联起来——ng-include引入的html并没有使用你定义的component控制器,所以open()函数根本没被绑定到对应的作用域上。 - Component定义语法错误:注册component时,第一个参数应该是组件的名称(字符串类型),而不是空数组,比如
.component('adminHeader', head)才是正确的写法。 - 直接操作DOM不符合AngularJS规范:用jQuery的
$('.menu-out').toggle()直接操作DOM,违背了AngularJS的数据绑定思想,容易引发作用域和视图不同步的问题。
二、解决方案一:修复ng-include的方式(保留ng-include)
这种方式适合你不想改动现有index.html结构的情况:
修改header.js
不用定义component,改为定义一个控制器,然后在ng-include时关联这个控制器:
(function(){ 'use strict'; angular.module('adminApp') .controller('HeaderCtrl', HeaderCtrl); HeaderCtrl.$inject = ["$scope"]; function HeaderCtrl($scope){ // 用AngularJS的变量控制显示隐藏,避免直接操作DOM $scope.isMenuOpen = false; $scope.open = function(){ $scope.isMenuOpen = !$scope.isMenuOpen; } } })();
修改index.html的ng-include
在ng-include里通过ng-controller关联控制器:
<div ng-include="'app/components/include/header.html'" ng-controller="HeaderCtrl"></div>
修改header.html
用ng-show或ng-class绑定变量来控制菜单显示:
<section class="admin-header"> <div class="row"> <div class="col-lg-9 col-md-9 col-sm-9 col-xs-9"> <h1>Admin test</h1> </div> <div class="col-lg-3 col-md-3 col-sm-3 col-xs-3" id="login" align="center"> <button type="button" class="btn btn-user" ng-click="open()"> <span class="glyphicon glyphicon-menu-hamburger" aria-hidden="true"></span> </button> </div> </div> </section> <!-- 用ng-show绑定变量控制显示 --> <div class="menu-out" ng-show="isMenuOpen"> <button type="button" class="btn btn-logout">Logout</button> </div>
三、解决方案二:改用Component组件方式(推荐)
AngularJS的component更适合复用组件,这种方式更规范:
修改header.js
修正component的注册语法,并且用组件的控制器和绑定:
(function(){ 'use strict'; var adminHeader = { templateUrl: '/app/components/include/header.html', controller: HeaderCtrl }; angular.module('adminApp') // 这里给组件起个名字,比如adminHeader .component('adminHeader', adminHeader); HeaderCtrl.$inject = ["$scope"]; function HeaderCtrl($scope){ $scope.isMenuOpen = false; $scope.open = function(){ $scope.isMenuOpen = !$scope.isMenuOpen; } } })();
修改index.html
去掉ng-include,改用组件标签:
<!-- 用组件标签替代ng-include --> <admin-header></admin-header> <ng-view></ng-view>
修改header.html(和方案一一样,用数据绑定)
<section class="admin-header"> <div class="row"> <div class="col-lg-9 col-md-9 col-sm-9 col-xs-9"> <h1>Admin test</h1> </div> <div class="col-lg-3 col-md-3 col-sm-3 col-xs-3" id="login" align="center"> <button type="button" class="btn btn-user" ng-click="open()"> <span class="glyphicon glyphicon-menu-hamburger" aria-hidden="true"></span> </button> </div> </div> </section> <div class="menu-out" ng-show="isMenuOpen"> <button type="button" class="btn btn-logout">Logout</button> </div>
四、解答你的疑惑
- 不需要在路由中处理头部:头部是所有页面公共的,直接放在index.html的ng-view外面即可,路由只负责处理页面主体内容(ng-view里的部分)。
- 不需要使用$rootScope:$rootScope是全局作用域,滥用会导致难以维护的代码,我们通过控制器或组件的本地作用域就可以实现需求,完全不需要用到$rootScope。
内容的提问来源于stack exchange,提问作者Chuck Villavicencio
相关产品推荐
相关产品推荐

