AngularJS 控制器
AngularJS 控制器 (Controller) 学习笔记控制器是 AngularJS 应用的核心组件之一负责初始化应用状态、定义行为逻辑并作为视图HTML和模型Scope之间的桥梁。一、控制器的基本概念1. 什么是控制器定义JavaScript 构造函数用于初始化$scope对象。作用设置初始状态数据。定义行为方法。响应视图中的用户交互。生命周期当 AngularJS 遇到ng-controller指令时创建当 DOM 元素被销毁时销毁。2. 定义控制器的两种方式方式 A全局注册推荐用于简单应用varappangular.module(myApp,[]);// 定义控制器app.controller(MyController,function($scope,$http){$scope.messageHello World;$scope.users[];// 方法$scope.addUserfunction(name){$scope.users.push({name:name});};});方式 B模块内匿名定义不推荐难以测试angular.module(myApp,[]).controller(MyController,function($scope){$scope.dataTest;});二、控制器语法风格1.$scope语法传统app.controller(UserCtrl,function($scope,$http){$scope.user{name:John,age:25};$scope.savefunction(){$http.post(/api/save,$scope.user);};});优点简单直观适合小型应用。缺点容易混淆$scope和this在嵌套作用域中容易出错。2.ControllerAs语法推荐AngularJS 1.3app.controller(UserCtrl,function($http){varvmthis;// 使用 vm (ViewModel) 作为 this 的别名vm.user{name:John,age:25};vm.savefunction(){$http.post(/api/save,vm.user);};});!-- 视图中使用 --divng-controllerUserCtrl as userCtrlinputng-modeluserCtrl.user.namebuttonng-clickuserCtrl.save()保存/button/div优点避免原型继承陷阱。代码更清晰易于阅读和维护。便于单元测试不依赖$scope。支持 ES6 Class 语法。3. 混合使用不推荐// ❌ 避免混用app.controller(BadCtrl,function($scope){this.dataBad;$scope.otherWorse;});三、依赖注入 (Dependency Injection)控制器通过依赖注入获取服务Services、过滤器Filters等。1. 隐式注入不推荐压缩后失效app.controller(MyCtrl,function($scope,$http){...});// 压缩后变成 function(a, b) { ... }Angular 无法识别参数名2. 数组注解法推荐生产环境标准app.controller(MyCtrl,[$scope,$http,function($scope,$http){// 逻辑代码}]);3. 显式$inject属性推荐代码整洁functionMyCtrl($scope,$http){// 逻辑代码}MyCtrl.$inject[$scope,$http];app.controller(MyCtrl,MyCtrl);四、控制器的作用域与继承1. 作用域链控制器创建一个新的$scope对象。子控制器继承父控制器的$scope原型链继承。注意在子 Scope 中修改对象属性是安全的但修改原始类型字符串、数字会创建新属性破坏继承链。// 父控制器app.controller(ParentCtrl,function($scope){$scope.data{value:10};// 对象$scope.count5;// 原始类型});// 子控制器app.controller(ChildCtrl,function($scope){$scope.data.value20;// ✅ 修改对象属性影响父级$scope.count10;// ❌ 创建新属性不影响父级});2. 隔离作用域指令中指令可以使用scope: {}创建隔离作用域不继承父控制器。控制器通常不直接创建隔离作用域而是通过指令实现。五、控制器生命周期钩子AngularJS 控制器没有像 Vue 那样的显式生命周期钩子但可以通过以下方式模拟1. 初始化逻辑直接在构造函数中执行。app.controller(InitCtrl,function($scope,$http){// 初始化$scope.loadDatafunction(){$http.get(/api/data).then(function(response){$scope.dataresponse.data;});};// 立即执行$scope.loadData();});2. 销毁钩子监听$destroy事件。app.controller(DestroyCtrl,function($scope){$scope.$on($destroy,function(){// 清理定时器、事件监听器等console.log(控制器销毁);});});六、控制器通信方式1. 父子控制器通信父传子通过$scope属性绑定。子传父通过$scope.$emit或回调函数。// 父控制器app.controller(ParentCtrl,function($scope){$scope.parentDataParent;$scope.onChildEventfunction(data){console.log(收到子级事件:,data);};});// 子控制器app.controller(ChildCtrl,function($scope){$scope.sendToParentfunction(){$scope.$emit(childEvent,Hello Parent);};$scope.$on(childEvent,function(event,data){$scope.parentDatadata;// 注意这里需要处理作用域});});2. 兄弟控制器通信通过$rootScope或共享服务Service。推荐使用 Service 作为单例共享数据。// 共享服务app.service(SharedService,function(){this.dataShared Data;this.updateDatafunction(newData){this.datanewData;};});// 控制器 Aapp.controller(CtrlA,function($scope,SharedService){$scope.updatefunction(){SharedService.updateData(New Data);};});// 控制器 Bapp.controller(CtrlB,function($scope,SharedService){$scope.$watch(function(){returnSharedService.data;},function(newVal){$scope.sharedDatanewVal;});});七、最佳实践1. 保持控制器轻量控制器只负责视图逻辑。业务逻辑、数据访问放入Service。DOM 操作放入Directive。// ❌ 糟糕的控制器app.controller(BadCtrl,function($scope,$http){$scope.fetchDatafunction(){// 复杂的业务逻辑// 直接操作 DOMdocument.getElementById(div).style.colorred;};});// ✅ 优秀的控制器app.controller(GoodCtrl,function($scope,DataService){$scope.data[];$scope.fetchDatafunction(){DataService.getData().then(function(result){$scope.dataresult;});};});2. 使用ControllerAs语法提高代码可读性。避免$scope陷阱。便于测试。3. 避免在控制器中直接操作 DOM使用ng-class,ng-style,ng-show等指令。复杂 DOM 操作使用Directive。4. 错误处理app.controller(ErrorCtrl,function($scope,$http){$scope.fetchDatafunction(){$http.get(/api/data).then(function(response){$scope.dataresponse.data;}).catch(function(error){$scope.error加载失败: error.message;});};});5. 内存泄漏预防在$destroy事件中清理定时器、事件监听器。$scope.$on($destroy,function(){clearInterval($scope.timer);$scope.$off(customEvent);});八、常见陷阱与解决方案问题原因解决方案数据不更新异步回调中未触发$apply使用$timeout或$scope.$apply()原型继承污染直接修改原始类型属性使用对象包裹数据 ($scope.data {})控制器重复初始化指令重复使用ng-controller检查 HTML 结构避免嵌套重复内存泄漏未清理定时器或事件监听在$destroy事件中清理测试困难依赖$scope隐式注入使用ControllerAs 数组注解法九、总结AngularJS 控制器的核心要点职责单一只处理视图逻辑业务逻辑交给 Service。语法选择优先使用ControllerAs语法避免$scope陷阱。依赖注入使用数组注解法或$inject属性确保代码可压缩。通信机制父子通过$scope兄弟通过 Service 或$rootScope。生命周期利用$destroy事件清理资源防止内存泄漏。测试友好保持控制器轻量便于单元测试。通过遵循这些最佳实践可以构建出结构清晰、易于维护的 AngularJS 应用。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2541355.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!