资讯专栏INFORMATION COLUMN

AngularJS 2 组件交流方式

Forest10 / 1858人阅读

摘要:方式,定义了的钩子也是可以引用的直接观察某一个子组件调用的时候变身啦超级赛亚人变身啦超级赛亚人可以思考一下,是否任何形式的父组件流入子组件的方式,都可以触发方法。其中,需要注意的是作用域的隔离,子组件可以很好的隔离作用域。

以下的测试例子都可以在 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

请输入 Baby 的名字:

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

我是子组件的属性(babyName) => {{babyName}}

我是跟父组件来:{{inputBabyName}}

我是 aliasBabyName => aliasName:{{aliasName}}

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

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

// Child component
_filterName: string = "";
    
@Input()
set filterName(n: string) {
    this._filterName = n + "wowo~~~";
}
    
get filterName() {
    return this._filterName;
}
// Parent html

这个其实也是用 @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 对象,这个对象可以是 Subject 的形式存在,也就是可以使用 RxJS 的思想来做,其中 T 范型表示定义需要传入的数据具体类型。

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

// 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 {
    
    babyName: string;
    
    constructor() { }
    
    ngOnInit() {
    this.babyName = "小撸一号";
    }
    
    changeBabyName(newBabyName) {
        this.babyName = newBabyName;
    }
 
}
// Parent html

BabyName:{{babyName}}

import { Component, OnInit, Output, EventEmitter } from "@angular/core";
    
@Component({
    selector: "app-child",
    templateUrl: "./child.component.html",
    styleUrls: ["./child.component.css"]
})
export class ChildComponent implements OnInit {
    
    @Output()
    changeBabyName: EventEmitter = new EventEmitter();
    
    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);
    }
}

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

(3) 无关组件的通信

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

事件回调传来传去的方式

Service 的注入

# 钩子的方式

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

// 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 {
    
    babyName: string = "小撸一号";
    
    constructor() { }
    
    ngOnInit() {
    }
    
}
// Parent html

    


// Child component
import { Component, OnInit, Input } from "@angular/core";
    
@Component({
    selector: "app-child",
    templateUrl: "./child.component.html",
    styleUrls: ["./child.component.css"]
})
export class ChildComponent implements OnInit {
    
    @Input() childName: string;
    
    constructor() { }
    
    ngOnInit() {
    }
    
}

Child:{{childName}}

// OtherChild component
import { Component, OnInit, 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

otherChild:{{helloBaby}}

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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/91341.html

相关文章

  • 【译】《精通使用AngularJS开发Web App》(一) --- 相关背景、社区、工具介绍

    摘要:下一篇译精通使用开发二原版书名第一章之道这一章主要是介绍,包括这个框架以及它背后的项目。幸运的是,拥有一个活跃的,支持度高的社区。另外,社区还为已经存在的工具箱里贡献了许多有意思的工具。 下一篇:【译】《精通使用AngularJS开发Web App》(二) 原版书名:Mastering Web Application Development with AngularJS Ch...

    ddongjian0000 评论0 收藏0
  • Angular 4 简单入门笔记

    摘要:首先,我们需要在入口页面的中配置根路径然后创建一个路由模块路由配置在主模块中导入配置好的路由模块而在页面中需要一个容器去承载上面代码中的定义了用户点击后的路由跳转,定义该路由激活时的样式类。 刚实习的时候用过AngularJS,那时候真的是连原生JavaScript都不会写,依样画葫芦做了几个管理后台。然后突然换项目了,AngularJS就不写了,感觉前前后后接触了一年多的Angula...

    whlong 评论0 收藏0
  • 一个基于Angular+Ionic+Phonegap的混合APP实战

    摘要:有二维码扫描功能,还做了类似消息可拖拽效果,上拉下拉刷新,轮播图组件。特别适合用于基于模式的移动应用程序开发。简介是一个用基于,和的,创建移动跨平台移动应用程序的快速开发平台。 这个项目做得比较早,当时是基于ionic1和angular1做的。做了四个tabs的app,首页模仿携程首页,第二页主要是phonegap调用手机核心功能,第三页模仿微信和qq聊天页,第四页模仿一般手机的表单设...

    孙淑建 评论0 收藏0
  • 割裂的前端工程师--- 2017年前端生态窥探

    摘要:主要兼容的微信的浏览器,因为要在朋友圈来营销,总体来说,会偏设计以及动画些。 有一天,我们组内的一个小伙伴突然问我,你知道有一个叫重构工程师的岗位?这是干什么的?重构工程师 这个问题引发了我对前端领域发展的思考,所以我来梳理下前端领域的发展过程,顺便小小的预测下2017年的趋势。不想看回忆的,可以直接跳到后面看展望。 神说,要有光,就有了光 自1991年蒂姆·伯纳斯-李公开提及HTML...

    duan199226 评论0 收藏0
  • 割裂的前端工程师--- 2017年前端生态窥探

    摘要:主要兼容的微信的浏览器,因为要在朋友圈来营销,总体来说,会偏设计以及动画些。 有一天,我们组内的一个小伙伴突然问我,你知道有一个叫重构工程师的岗位?这是干什么的?重构工程师 这个问题引发了我对前端领域发展的思考,所以我来梳理下前端领域的发展过程,顺便小小的预测下2017年的趋势。不想看回忆的,可以直接跳到后面看展望。 神说,要有光,就有了光 自1991年蒂姆·伯纳斯-李公开提及HTML...

    miguel.jiang 评论0 收藏0

发表评论

0条评论

Forest10

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<