You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 22:50:45