简体   繁体   English

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

[英]In angular js, How do I pass data from a parent controller to a child controller?

I have a little widget I'd like to use over and over on a single page. 我有一个小小部件,我想在一个页面上反复使用。 It has its own controller. 它有自己的控制器。 Problem is it needs a piece of data to operate (basically a key), and each key is contained in the parent controller. 问题是它需要一个数据来操作(基本上是一个键),每个键都包含在父控制器中。

Here is an example (which is obviously wrong) 这是一个例子(显然是错误的)

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

script: 脚本:

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
    }
  ])

index: 指数:

    <!-- 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>

chartwidget: chartwidget:

<div ng-controller="ChartCtrl">
    <p>Drawing chart for data: {{key}}</p>
    <p>some chart directive here</p>
</div>

As you can see in the plunker, what I tried here with ng-init doesn't work - key for all the sub-controllers end up with the same value. 正如你在plunker中看到的那样,我在这里用ng-init尝试的东西不起作用 - 所有子控制器的键最终都具有相同的值。

I've gotten this to work with ng-repeat and an array of data in the parent, somehow $index gets set in each child to the right index and stays that one value. 我已经使用ng-repeat和父数据库中的一组数据,不知何故$ index将每个子项设置为正确的索引并保留一个值。 But I'd like to avoid using ng-repeat in this case so I can have more control of the layout. 但是我想在这种情况下避免使用ng-repeat,这样我就可以更好地控制布局了。

Creating re-usable widgets is exactly the purpose of Directives. 创建可重用的小部件正是指令的目的。 You can create a directive which handles the output of your widget quite easily. 您可以创建一个指令来轻松处理窗口小部件的输出。

I forked your plunker and modified it to change it to use a directive. 我分叉你的plunker并修改它以改变它以使用指令。

Here are a few highlights: 以下是一些亮点:

First, your template no longer needs the controller defined within it. 首先,您的模板不再需要在其中定义的控制器。

<div>
    <p>Drawing chart for data: {{key}}</p>
    <p>some chart directive here</p>
</div>

Next, the directive is defined, with an isolate scope which is unique to each instance of the directive: 接下来,定义了一个指令,它具有一个隔离范围,该范围对于该指令的每个实例都是唯一的:

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

Lastly, the directive is declared in the HTML. 最后,该指令在HTML中声明。 Note the camel-case name of the directive in the JavaScript, but the hyphenated name in the 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>

Edit 编辑

I updated the plunker to show binding the directive property to an inner controller. 我更新了plunker以显示将指令属性绑定到内部控制器。 This method uses the ControllerAs syntax to define the controller, and binds the directive's scope to the controller scope. 此方法使用ControllerAs语法定义控制器,并将指令的作用域绑定到控制器作用域。

Relevant changes: 相关变化:

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

And a small change to the template to support ControllerAs: 对模板进行一些小改动以支持ControllerAs:

<div>
    <p>Drawing chart for data: {{ctrl.key}}</p>
    <p>some chart directive here</p>
</div>

Note that trying to use ng-controller= in the template will cause the template to have a different scope object from the scope object created for the directive, and the controller would not have access to the properties defined on the directive. 请注意,尝试在模板中使用ng-controller=将导致模板与为指令创建的范围对象具有不同的范围对象,并且控制器将无法访问指令上定义的属性。

Also note, bindToController is a feature of angular 1.3.x or higher. 另请注意, bindToController是角度1.3.x或更高的功能。 in angular 1.2.x or earlier, your only option was to use $scope.$watch to monitor the isolate scope for changes. 在角度1.2.x或更早版本中,您唯一的选择是使用$scope.$watch来监视隔离范围的变化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM