在角度js中,如何将数据从父控制器传递到子控制器? [英] In angular js, How do I pass data from a parent controller to a child controller?

查看:66
本文介绍了在角度js中,如何将数据从父控制器传递到子控制器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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 =预览

脚本:

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

指数:

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

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

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.

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

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. But I'd like to avoid using ng-repeat in this case so I can have more control of the layout.

推荐答案

创建可重复使用的小部件正是指令的目的。你可以很容易地创建一个处理窗口小部件输出的指令。

Creating re-usable widgets is exactly the purpose of Directives. You can create a directive which handles the output of your widget quite easily.

我分叉你的 plunker 并修改它以将其更改为使用指令。

I forked your plunker and modified it to change it to use a directive.

以下是一些亮点:

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

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

最后,该指令在HTML中声明。请注意JavaScript中指令的驼峰名称,但HTML中带有连字符的名称:

Lastly, the directive is declared in the HTML. Note the camel-case name of the directive in the JavaScript, but the hyphenated name in the HTML:

<div>
    <chart-widget key="keyForChartABC"></chart-widget>
    <hr>
    <chart-widget key="keyForChartXYZ"></chart-widget>
    <hr>
    <chart-widget key="keyForChartLALA"></chart-widget>
</div>

修改

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

I updated the plunker to show binding the directive property to an inner controller. This method uses the ControllerAs syntax to define the controller, and binds the directive's scope to the controller scope.

相关更改:

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

对模板进行小幅更改以支持ControllerAs:

And a small change to the template to support ControllerAs:

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

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

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.

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

Also note, bindToController is a feature of angular 1.3.x or higher. in angular 1.2.x or earlier, your only option was to use $scope.$watch to monitor the isolate scope for changes.

这篇关于在角度js中,如何将数据从父控制器传递到子控制器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆