AngularJS同模块组件间如何实现数据传递?
解决方案:AngularJS 组件间数据传递
在 AngularJS 中,直接使用全局 window 对象无法触发框架的脏检查机制,导致视图无法更新,同时初始值未定义的问题也会引发渲染异常。推荐使用以下两种规范的组件通信方式:
方案一:父级作用域作为数据桥梁(适合组件有共同父级场景)
通过父控制器/组件统一管理数据,子组件通过绑定实现数据传递和回调。
1. 父控制器与模板
<!-- 父模板 --> <div ng-controller="InfoSystemCtrl"> <info-getter info-list="infoArray" on-select="selectInfo(item)" ></info-getter> <info-displayer selected-info="selectedInfo"></info-displayer> </div>
// 父控制器 angular.module('info-system') .controller('InfoSystemCtrl', function($scope) { // 初始化数据数组 $scope.infoArray = [ {id: 1, name: "信息1", content: "内容详情1"}, {id: 2, name: "信息2", content: "内容详情2"} ]; // 初始化选中项,避免未定义问题 $scope.selectedInfo = null; // 接收子组件传递的选中项 $scope.selectInfo = function(item) { $scope.selectedInfo = item; }; });
2. info-getter 组件定义
angular.module('info-system') .component('infoGetter', { // 单向绑定数据数组,绑定回调函数 bindings: { infoList: '<', onSelect: '&' }, template: ` <ul> <li ng-repeat="item in $ctrl.infoList track by $index" ng-click="$ctrl.onSelect({item: item})" > {{ item.name }} </li> </ul> ` });
3. info-displayer 组件定义
angular.module('info-system') .component('infoDisplayer', { // 单向绑定选中项 bindings: { selectedInfo: '<' }, template: ` <div ng-if="$ctrl.selectedInfo"> <h3>选中信息详情</h3> <p>ID: {{ $ctrl.selectedInfo.id }}</p> <p>内容: {{ $ctrl.selectedInfo.content }}</p> </div> <div ng-if="!$ctrl.selectedInfo"> 请选择一条信息 </div> ` });
方案二:共享服务(适合无共同父级或跨组件共享数据场景)
利用 AngularJS 服务的单例特性,统一管理数据和状态。
1. 共享数据服务
angular.module('info-system') .service('infoShareService', function() { // 存储数据数组 this.infoArray = [ {id: 1, name: "信息1", content: "内容详情1"}, {id: 2, name: "信息2", content: "内容详情2"} ]; // 初始化选中项 this.selectedInfo = null; // 设置选中项的方法 this.setSelectedInfo = function(index) { this.selectedInfo = this.infoArray[index]; }; // 获取选中项的方法 this.getSelectedInfo = function() { return this.selectedInfo; }; });
2. info-getter 组件
angular.module('info-system') .component('infoGetter', { controller: function(infoShareService) { var ctrl = this; // 从服务获取数据数组 ctrl.infoList = infoShareService.infoArray; // 点击时调用服务方法设置选中项 ctrl.onItemClick = function(index) { infoShareService.setSelectedInfo(index); }; }, template: ` <ul> <li ng-repeat="item in $ctrl.infoList track by $index" ng-click="$ctrl.onItemClick($index)" > {{ item.name }} </li> </ul> ` });
3. info-displayer 组件
angular.module('info-system') .component('infoDisplayer', { controller: function(infoShareService, $scope) { var ctrl = this; // 初始化选中项 ctrl.selectedInfo = infoShareService.getSelectedInfo(); // 监听服务中选中项的变化,自动更新视图 $scope.$watch(function() { return infoShareService.selectedInfo; }, function(newVal) { ctrl.selectedInfo = newVal; }); }, template: ` <div ng-if="$ctrl.selectedInfo"> <h3>选中信息详情</h3> <p>ID: {{ $ctrl.selectedInfo.id }}</p> <p>内容: {{ $ctrl.selectedInfo.content }}</p> </div> <div ng-if="!$ctrl.selectedInfo"> 请选择一条信息 </div> ` });
为什么全局 window 方案不可行?
AngularJS 的视图更新依赖自身的脏检查机制,全局 window 对象的变化不会触发框架的 $digest 循环,因此视图无法同步更新。同时初始时 window.indexGot 未定义,会导致模板渲染时出现异常,而通过上述方案初始化选中项为 null 可避免该问题。
内容的提问来源于stack exchange,提问作者Mongrel
相关产品推荐
相关产品推荐

