在我正在从事的新项目中,我开始使用组件而不是指令。
但是,我遇到一个无法找到具体标准方法的问题。
从孩子向父母通知事件很容易,您可以在下面的我的plunkr上找到它,但是从父母向孩子通知事件的正确方法是什么?
Angular2似乎通过使用以下方法解决了此问题:https ://angular.io/docs/ts/latest/cookbook/component-communication.html#!#parent- to-child-local-var 但是我不知道可以像在#timer中所做的那样,为子组件定义一个“指针”
为了保持向Angular2的轻松转换,我想避免:
示例代码:
var app = angular.module('plunker', []); app.controller('RootController', function() { }); app.component('parentComponent', { template: ` <h3>Parent component</h3> <a class="btn btn-default btn-sm" ng-click="$ctrl.click()">Notify Child</a> <span data-ng-bind="$ctrl.childMessage"></span> <child-component on-change="$ctrl.notifiedFromChild(count)"></child-component> `, controller: function() { var ctrl = this; ctrl.notifiedFromChild = function(count){ ctrl.childMessage = "From child " + count; } ctrl.click = function(){ } }, bindings: { } }); app.component('childComponent', { template: ` <h4>Child component</h4> <a class="btn btn-default btn-sm" ng-click="$ctrl.click()">Notify Parent</a> `, controller: function() { var ctrl = this; ctrl.counter = 0; ctrl.click = function(){ ctrl.onChange({ count: ++ctrl.counter }); } }, bindings: { onChange: '&' } });
您可以在此处找到示例:
http://plnkr.co/edit/SCK8XlYoYCRceCP7q2Rn?p=preview
这是我创建的可能解决方案
http://plnkr.co/edit/OfANmt4zLyPG2SZyVNLr?p=preview
孩子需要父母的地方,然后孩子为孩子设置了父母的引用…现在父母可以使用孩子了…丑陋,但就像上面的angular2示例
要允许父组件将事件传达给子组件,请让子组件发布API:
<grid-component grid-on-init="$ctrl.gridApi=$API; $ctrl.someFn($API)"> </grid-component>
JS
app.component('gridComponent', { //Create API binding bindings: {gridOnInit: "&"}, template: ` <h4>Grid component</h4> <p> Save count = {{$ctrl.count}}</p> `, controller: function() { var ctrl = this; this.$onInit = function() { ctrl.count = 0; ctrl.api = {}; //Publish save function ctrl.api.save = save; //Invoke Expression with $API as local ctrl.gridOnInit({$API: ctrl.api}); }; function save(){ console.log("saved!"); ctrl.count++; } } });
上面的示例调用grid-on-init属性定义的Angular Expression ,其API公开为$API。这种方法的优点是,父级可以通过将函数传递给带有Angular Expression的子级组件来对子级初始化做出反应。
grid-on-init
$API
从文档中:
“隔离”范围对象哈希定义了一组从指令元素上的属性派生的局部范围属性。这些本地属性对于为模板的别名设置别名很有用。对象哈希中的键映射到隔离范围内的属性的名称。这些值通过匹配指令元素上的属性来定义如何将属性绑定到父作用域: &或&attr-提供一种在父作用域的上下文中执行表达式的方法。如果未指定attr名称,则假定属性名称与本地名称相同。给定<my- component my-attr="count = count + value">和隔离范围定义scope:{ localFn:'&myAttr' },isolate scope属性localFn将指向的函数包装count = count + value expression。通常,需要将数据从隔离范围通过表达式传递到父范围。这可以通过将局部变量名称和值的映射传递到表达式包装器fn中来完成。例如,如果表达式为,increment($amount)则可以通过调用localFnas 来指定金额值localFn({$amount: 22})。
“隔离”范围对象哈希定义了一组从指令元素上的属性派生的局部范围属性。这些本地属性对于为模板的别名设置别名很有用。对象哈希中的键映射到隔离范围内的属性的名称。这些值通过匹配指令元素上的属性来定义如何将属性绑定到父作用域:
&
&attr
<my- component my-attr="count = count + value">
{ localFn:'&myAttr' }
localFn
count = count + value expression
increment($amount)
localFn({$amount: 22})
- AngularJS综合指令API -范围
按照惯例,我建议给局部变量加上前缀,$以将其与父变量区分开。
$
注意: 为简化向Angular 2+的过渡,请避免使用双向=绑定。而是使用单向<绑定和表达式&绑定。有关更多信息,请参阅《AngularJS开发人员指南- 了解组件》。
=
<
<grid-component api="$ctrl.gridApi"></grid-component>
在上面的示例中,grid-component使用api属性使用绑定将其API发布到父级作用域上。
grid-component
api
app.component('gridComponent', { //Create API binding bindings: {api: "="}, template: ` <h4>Grid component</h4> <p> Save count = {{$ctrl.count}}</p> `, controller: function() { var ctrl = this; this.$onInit = function() { ctrl.count = 0; ctrl.api = {}; //Publish save function ctrl.api.save = save; }; function save(){ console.log("saved!"); ctrl.count++; } } });
然后,父组件可以save使用已发布的API 调用子函数:
save
ctrl.click = function(){ console.log("Search clicked"); ctrl.gridApi.save(); }
在上PLNKR DEMO。