在角度js中,如何将数据从父控制器传递到子控制器?

ada*_*dev 2 javascript angularjs

我有一个小小部件,我想在一个页面上反复使用.它有自己的控制器.问题是它需要一个数据来操作(基本上是一个键),每个键都包含在父控制器中.

这是一个例子(显然是错误的)

http://plnkr.co/edit/VajgOr1LqpLDnbEJcvor?p=preview

脚本:

angular.module('myApp', [])
  .controller('ParentCtrl', ['$scope',
    function($scope) {
      $scope.keyForChartABC = "somekey1";
      $scope.keyForChartXYZ = "somekey2";
      $scope.keyForChartLALA = "somekey3";

    }
  ])
  .controller('ChartCtrl', ['$scope',
    function($scope) {
      //todo: have $scope.key assigned from parent somehow

      //not shown:  use $scope.key to pull data and format chart data
    }
  ])
Run Code Online (Sandbox Code Playgroud)

指数:

    <!-- ng-init like this is quite wrong -->
    <div    ng-init="key = keyForChartABC"
            ng-include="'chartwidget.html'"></div>
    <hr>
    <div    ng-init="key = keyForChartXYZ"
            ng-include="'chartwidget.html'"></div>
    <hr>
    <div    ng-init="key = keyForChartLALA"
            ng-include="'chartwidget.html'"></div>
Run Code Online (Sandbox Code Playgroud)

chartwidget:

<div ng-controller="ChartCtrl">
    <p>Drawing chart for data: {{key}}</p>
    <p>some chart directive here</p>
</div>
Run Code Online (Sandbox Code Playgroud)

正如你在plunker中看到的那样,我在这里用ng-init尝试的东西不起作用 - 所有子控制器的键最终都具有相同的值.

我已经使用ng-repeat和父数据库中的一组数据,不知何故$ index将每个子项设置为正确的索引并保留一个值.但是我想在这种情况下避免使用ng-repeat,这样我就可以更好地控制布局了.

Cla*_*ies 7

创建可重用的小部件正是指令的目的.您可以创建一个指令来轻松处理窗口小部件的输出.

我分叉你的plunker并修改它以改变它以使用指令.

以下是一些亮点:

首先,您的模板不再需要在其中定义的控制器.

<div>
    <p>Drawing chart for data: {{key}}</p>
    <p>some chart directive here</p>
</div>
Run Code Online (Sandbox Code Playgroud)

接下来,定义了一个指令,它具有一个隔离范围,该范围对于该指令的每个实例都是唯一的:

.directive('chartWidget', function(){
    return {
      restrict: 'E',
      scope: {
        key: '='
      },
      templateUrl : 'chartwidget.html'
    }
})
Run Code Online (Sandbox Code Playgroud)

最后,该指令在HTML中声明.请注意JavaScript中指令的camel-case名称,但HTML中带有连字符的名称:

<div>
    <chart-widget key="keyForChartABC"></chart-widget>
    <hr>
    <chart-widget key="keyForChartXYZ"></chart-widget>
    <hr>
    <chart-widget key="keyForChartLALA"></chart-widget>
</div>
Run Code Online (Sandbox Code Playgroud)

编辑

我更新了plunker以显示将指令属性绑定到内部控制器.此方法使用ControllerAs语法定义控制器,并将指令的作用域绑定到控制器作用域.

相关变化:

.directive('chartWidget', function(){
    return {
      restrict: 'E',
      scope: {
        key: '='
      },
      templateUrl : 'chartwidget.html',
      controller: 'chartWidgetController',
      controllerAs: 'ctrl',
      bindToController: true
    }
  })
  .controller('chartWidgetController', function(){
    console.log(this.key);
  })
Run Code Online (Sandbox Code Playgroud)

对模板进行一些小改动以支持ControllerAs:

<div>
    <p>Drawing chart for data: {{ctrl.key}}</p>
    <p>some chart directive here</p>
</div>
Run Code Online (Sandbox Code Playgroud)

请注意,尝试ng-controller=在模板中使用将导致模板具有与为指令创建的范围对象不同的范围对象,并且控制器将无法访问指令上定义的属性.

另请注意,bindToController角度为1.3.x或更高的功能.在角度1.2.x或更早版本中,您唯一的选择是$scope.$watch用于监视隔离范围的更改.

  • 是的,但是在指令上处理控制器的正确方法是将其添加为JavaScript中的属性.我将通过一个例子更新我的答案 (2认同)