以下的测试例子都可以在 github 找到,但是最近好像不太稳定。

其实 ng2 在这方面做得挺好的,用起来也很简单,所以看完基本就可以动手写一写。强大并不止是这一方面,在写这些的过程中,通过一些配置,让开发很纯粹,有时间再录一个新手入门的开发教程。

(1) 父组件向子组件流入数据

这种方式是最简单的,在 ng2 中处理得非常完美,通过在子组件中标记 @input() 输入接口的方式进行接收父组件的值,我下面的 demo 主要分了几种场景,尽可能的多覆盖不同情况吧。

基本上例子中覆盖了常见的情况:

  • 直接传入一个字符串的情况,不需要绑定父组件的一个变量

  • 绑定父组件变量的情况,然后可以在父组件中不断修改

  • 输入别名的情况,可以在子组件中对输入的变量名进行重新设置

  • ngOnChanges() 在子组件中监听属性的修改

  • 特殊情况下,我们需要对父组件传入的数据进行过滤

  • @ViewChild() 注解的跨多层子组件的观察方式

说了这么多,来看一下实际的代码吧。

// Parent component
import { Component,OnInit } from '@angular/core';
    
@Component({
    selector: 'app-parent',templateUrl: './parent.component.html',styleUrls: ['./parent.component.css']
})
export class ParentComponent implements OnInit {
    
    baby: string = '你的名字';
    
    constructor() { }
    
    ngOnInit() {
    }
    
}
// Parent html
<h3>请输入 Baby 的名字:</h3>
<input [(ngModel)]="baby" type="text"> 
<app-child babyName="hello" [inputBabyName]="baby" aliasBabyName="我是别名"></app-child>
// Child component
import { Component,OnInit,Input,SimpleChange } from '@angular/core';

@Component({
    selector: 'app-child',templateUrl: './child.component.html',styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
    
    @input() babyName: string;
    @input() inputBabyName: string;
    @Input('aliasBabyName') aliasName: string;
    
    changes: string;
    
    constructor() { }
    
    ngOnInit() {
    }
    
    ngOnChanges(changes: SimpleChange) {
        this.changes = JSON.stringify(changes);
    }
}
// Child html
<h3>我是子组件的属性(babyName) => {{babyName}}</h3>
<h3 style="color:red;">我是跟父组件来:{{inputBabyName}}</h3>
<h3>我是 aliasBabyName => aliasName:{{aliasName}}</h3>

那么我需要过滤一下值要怎么弄呢?

这样我们就可以用到 setter 和 getter 的特性来做,具体如下:

// Child component
_filterName: string = '';
    
@input()
set filterName(n: string) {
    this._filterName = n + 'wowo~~~';
}
    
get filterName() {
    return this._filterName;
}
// Parent html
<app-child [filterName]="babyName"></app-child>

这个其实也是用 @input() 这个注解来做的,有点类似 computed 的概念吧,但是这样做对于习惯 Java 的小伙伴是很友好的,其实通过一些权限的设置,还能够更加的强大。

@ViewChild() 的方式

这种方式我觉得更多的是,我的沟通逻辑存在于 TS 中的时候就很实用。并且是描述性的定义方式,所以逻辑也是清晰的。

// Parent component
// 方式1,定义了 `#` 的钩子也是可以引用的
@ViewChild('child') cc: ChildComponent;
    
// 直接观察某一个子组件
@ViewChild(ChildComponent)
cc_other: ChildComponent;
    
// 调用的时候
this.cc.name = '变身啦!超级赛亚人';
this.cc_other.name = '变身啦!超级赛亚人 4';

可以思考一下,是否任何形式的父组件流入子组件的方式,都可以触发 ngOnChanges() 方法。

(2) 子组件向父组件通信

从软件的结构上来讲,是上层抽象对底层的具体实现是隐藏的,所以具体层的东西最好尽可能少的知道抽象层的事情,也许表达方式不一样,但是这样的话封闭性会好很多,更多的暴露是以某一个权限开放的接口形式。但是通信是很复杂的东西,就好像人与人之间的联系是一样的。好吧,我们来具体说一下子组件怎么访问父组件。主要通过的方式是:

  • 在子组件定义一个 @Output()EventEmitter<T> 对象,这个对象可以是 Subject 的形式存在,也就是可以使用 RxJS 的思想来做,其中 T 范型表示定义需要传入的数据具体类型。

  • 父组件中定义一个自己的函数来修改自身的信息,或者再传入其他子组件使用。

// Parent component
import { Component,styleUrls: ['./parent.component.css']
})
export class ParentComponent implements OnInit {
    
    babyName: string;
    
    constructor() { }
    
    ngOnInit() {
    this.babyName = '小撸一号';
    }
    
    changeBabyName(newBabyName) {
        this.babyName = newBabyName;
    }
 
}
// Parent html
<h3>BabyName:{{babyName}}</h3>
<app-child (changeBabyName)="changeBabyName($event)"></app-child>
import { Component,Output,EventEmitter } from '@angular/core';
    
@Component({
    selector: 'app-child',styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
    
    @Output()
    changeBabyName: EventEmitter<string> = new EventEmitter<string>();
    
    rhashcode = /\d\.\d{4}/;
    
    constructor() { }
    
    ngOnInit() {
    }
    
    getNewBabyName(e) {
        let newName = this.makeHashCode('小撸新号');
        this.changeBabyName.next(newName);
    }
    
    /* UUID http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript */
    makeHashCode(prefix) {
        prefix = prefix || '60sky';
        return String(Math.random() + Math.random()).replace(this.rhashcode,prefix);
    }
}
<button (click)="getNewBabyName($event)">我要改我自己的名字</button>

其中需要注意的是父组件中方法注入的 $event 对象,这个对象在这里注入的是子组件传入的值,所以在父组件中就可以直接使用了,我这里定义了 string 类型的数据,所以传入后定义接口的参数类型也是相对应的。

(3) 无关组件的通信

ng2 在无关组件的处理上,真的处理得很干脆,给你一个钩子,你用吧!就是这种简单的思路。这里我只介绍部分,因为官方文档有更加详细的介绍,不然我这篇文章就写得太长了~因为方式有很多种,发挥小聪明就能发现很多。

  • 事件回调传来传去的方式

  • Service 的注入

  • # 钩子的方式

这里介绍的是一个 # 钩子的方式来做,直接来代码吧,很方便的。
其中,需要注意的是作用域的隔离,子组件可以很好的隔离作用域。

// Parent component
import { Component,styleUrls: ['./parent.component.css']
})
export class ParentComponent implements OnInit {
    
    babyName: string = '小撸一号';
    
    constructor() { }
    
    ngOnInit() {
    }
    
}
// Parent html
<input [(ngModel)]="babyName" type="text">
    
<app-child #child [childName]="babyName"></app-child>
<app-otherChild helloBaby="child.childName"></app-otherChild>
// Child component
import { Component,Input } from '@angular/core';
    
@Component({
    selector: 'app-child',styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
    
    @input() childName: string;
    
    constructor() { }
    
    ngOnInit() {
    }
    
}
<h3 style="color:red;">Child:{{childName}}</h3>
// OtherChild component
import { Component,Input } from '@angular/core';
    
@Component({
    selector: 'app-otherChild',templateUrl: './otherChild.component.html',styleUrls: ['./otherChild.component.css']
})
export class OtherChildComponent implements OnInit {
    
    @input() helloBaby: string;
    
    constructor() { }
    
    ngOnInit() {
    }
    
    changeChildName(e) {
        this.helloBaby = '小撸新号';
    }
}
// OtherChild html
<h3 style="color:blue;">otherChild:{{helloBaby}}</h3>
<button (click)="changeChildName($event)">我来统一修改一下</button>

其实还有一些方式和特殊场景下的处理,所以总体来说,ng2 在这方面是不错的~

AngularJS 2 组件交流方式的更多相关文章

  1. HTML5 input新增type属性color颜色拾取器的实例代码

    type 属性规定 input 元素的类型。本文较详细的给大家介绍了HTML5 input新增type属性color颜色拾取器的实例代码,感兴趣的朋友跟随脚本之家小编一起看看吧

  2. 移动HTML5前端框架—MUI的使用

    这篇文章主要介绍了移动HTML5前端框架—MUI的使用的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  3. 使用placeholder属性设置input文本框的提示信息

    这篇文章主要介绍了使用placeholder属性设置input文本框的提示信息,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下

  4. Bootstrap File Input文件上传组件

    这篇文章主要介绍了Bootstrap File Input文件上传组件,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  5. HTML5 WebSocket实现点对点聊天的示例代码

    这篇文章主要介绍了HTML5 WebSocket实现点对点聊天的示例代码的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  6. HTML5中input输入框默认提示文字向左向右移动的示例代码

    这篇文章主要介绍了HTML5中input输入框默认提示文字向左向右移动,本文通过实例代码给大家介绍的非常详细对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  7. ios – 在Swift的UIView中找到UILabel

    我正在尝试在我的UIViewControllers的超级视图中找到我的UILabels.这是我的代码:这是在Objective-C中推荐的方式,但是在Swift中我只得到UIViews和CALayer.我肯定在提供给这个方法的视图中有UILabel.我错过了什么?我的UIViewController中的调用:解决方法使用函数式编程概念可以更轻松地实现这一目标.

  8. ios – 在Swift中将输入字段字符串转换为Int

    所以我非常擅长制作APP广告Swift,我试图在文本字段中做一些非常简单的输入,取值,然后将它们用作Int进行某些计算.但是’vardistance’有些东西不正确它是导致错误的最后一行代码.它说致命错误:无法解开Optional.None解决方法在你的例子中,距离是一个Int?否则称为可选的Int..toInt()返回Int?因为从String到Int的转换可能失败.请参阅以下示例:

  9. 如何在iOS中检测文本(字符串)语言?

    例如,给定以下字符串:我想检测每个声明的字符串中使用的语言.让我们假设已实现函数的签名是:如果没有检测到语言,则返回可选字符串.因此,适当的结果将是:有一个简单的方法来实现它吗?

  10. xamarin – 崩溃在AccountStore.Create().保存(e.Account,“);

    在Xamarin.Forms示例TodoAwsAuth中https://developer.xamarin.com/guides/xamarin-forms/web-services/authentication/oauth/成功登录后,在aOnAuthenticationCompleted事件中,应用程序在尝试保存到Xamarin.Auth时崩溃错误说不能对钥匙串说期待着寻求帮助.解决方法看看你

随机推荐

  1. Angular2 innerHtml删除样式

    我正在使用innerHtml并在我的cms中设置html,响应似乎没问题,如果我这样打印:{{poi.content}}它给了我正确的内容:``但是当我使用[innerHtml]=“poi.content”时,它会给我这个html:当我使用[innerHtml]时,有谁知道为什么它会剥离我的样式Angular2清理动态添加的HTML,样式,……

  2. 为Angular根组件/模块指定@Input()参数

    我有3个根组件,由根AppModule引导.你如何为其中一个组件指定@input()参数?也不由AppModalComponent获取:它是未定义的.据我所知,你不能将@input()传递给bootstraped组件.但您可以使用其他方法来做到这一点–将值作为属性传递.index.html:app.component.ts:

  3. angular-ui-bootstrap – 如何为angular ui-bootstrap tabs指令指定href参数

    我正在使用角度ui-bootstrap库,但我不知道如何为每个选项卡指定自定义href.在角度ui-bootstrap文档中,指定了一个可选参数select(),但我不知道如何使用它来自定义每个选项卡的链接另一种重新定义问题的方法是如何使用带有角度ui-bootstrap选项卡的路由我希望现在还不算太晚,但我今天遇到了同样的问题.你可以通过以下方式实现:1)在控制器中定义选项卡href:2)声明一个函数来改变控制器中的散列:3)使用以下标记:我不确定这是否是最好的方法,我很乐意听取别人的意见.

  4. 离子框架 – 标签内部的ng-click不起作用

    >为什么标签标签内的按钮不起作用?>但是标签外的按钮(登陆)工作正常,为什么?>请帮我解决这个问题.我需要在点击时做出回复按钮workingdemo解决方案就是不要为物品使用标签.而只是使用divHTML

  5. Angular 2:将值传递给路由数据解析

    我正在尝试编写一个DataResolver服务,允许Angular2路由器在初始化组件之前预加载数据.解析器需要调用不同的API端点来获取适合于正在加载的路由的数据.我正在构建一个通用解析器,而不是为我的许多组件中的每个组件设置一个解析器.因此,我想在路由定义中传递指向正确端点的自定义输入.例如,考虑以下路线:app.routes.ts在第一个实例中,解析器需要调用/path/to/resourc

  6. angularjs – 解释ngModel管道,解析器,格式化程序,viewChangeListeners和$watchers的顺序

    换句话说:如果在模型更新之前触发了“ng-change”,我可以理解,但是我很难理解在更新模型之后以及在完成填充更改之前触发函数绑定属性.如果您读到这里:祝贺并感谢您的耐心等待!

  7. 角度5模板形式检测形式有效性状态的变化

    为了拥有一个可以监听其包含的表单的有效性状态的变化的组件并执行某些组件的方法,是reactiveforms的方法吗?

  8. Angular 2 CSV文件下载

    我在springboot应用程序中有我的后端,从那里我返回一个.csv文件WheniamhittingtheURLinbrowsercsvfileisgettingdownloaded.现在我试图从我的角度2应用程序中点击此URL,代码是这样的:零件:服务:我正在下载文件,但它像ActuallyitshouldbeBook.csv请指导我缺少的东西.有一种解决方法,但您需要创建一个页面上的元

  9. angularjs – Angular UI-Grid:过滤后如何获取总项数

    提前致谢:)你应该避免使用jQuery并与API进行交互.首先需要在网格创建事件中保存对API的引用.您应该已经知道总行数.您可以使用以下命令获取可见/已过滤行数:要么您可以使用以下命令获取所选行的数量:

  10. angularjs – 迁移gulp进程以包含typescript

    或者我应该使用tsc作为我的主要构建工具,让它解决依赖关系,创建映射文件并制作捆绑包?

返回
顶部