美文网首页全栈Web开发者"老和"讲全栈WEB全栈技术
Angular 5.X 学习笔记——component之间的数据

Angular 5.X 学习笔记——component之间的数据

作者: 全栈开发之道 | 来源:发表于2018-04-14 18:21 被阅读33次
    序言

    这次学习笔记,来自国外的一篇教学案例,好东西就得分享。

    Angular Input Output Tutorial Example From Scratch

    Step 1: Install Angular Project via AngularCLI
    Step 2: Create parent and child components.
    Step 3: Define HTML for parent component
    Step 4: Define HTML for child component
    Step 5: Use Input to display parent component value
    Step 6: Pass value from child to parent component

    代码实现与解析

    第一步 创建一个project

    ng new input

    说明:
    (1) 在 AngularJS时代,创建一个NG工程很简单,只是在html文件中,引入 AngularJS即可。 进入 Angular 新时代后,是通过CLI 来创建工程的。 所以需要事先安装Angular 的 CLI。 而且,一旦创建就要默认生成很好很多文件, 自然,这个创建过程需要耐心的等待,花些时间是必须的。
    (2)在这个创建工程中,不仅仅是create 了一些文件,而且还自动生成了它的依赖包,也就是说,自动执行力 npm install。 整个工程 380M,一行代码还没写呢!

    (3) 一旦创建成功,你肯定会迫不及待地想运行看看效果。 通常,会不加思索地运行它。

    ng serve -o

    奇怪现象产生了,咦,不是说好了 hello world 会自动生成的吗? 怎么报这个错呢? 吓死宝宝了。 呵呵

    image.png

    当然,聪明的你,会想起百度学习法。在百度上搜索下看看, 搜索:
    You seem to not be depending on "@angular/core". This is an error.

    神人多了去了,招数也多了去了,有人告诉你,重新安装 Angular CLI; 有人告诉你重新 npm install, 甚至也有告诉你,重新安装 node.js 就差让你换一台电脑了。


    其实哪里有这么复杂,报错的意思,并不是说依赖关系出了问题,而是根本没找见 @angular/core 。 经验告诉我们,找不见文件,通常是路径出了问题。

    我们刚才创建了的工程路径是 input, 而指令所在的路径根本不是 input 啊! 这时候的你,肯定恍然大悟,原来如此!

    进入到该工程所在路径:

    cd input

    这时,再来运行以下

    ng serve -o

    奇迹出现了,世界是多么的其妙! 啥也不说了,看图吧:

    image.png

    重要的事情说三遍: 创建工程后,一定要进入到该工程所在的路径!
    重要的事情说三遍: 创建工程后,一定要进入到该工程所在的路径!
    重要的事情说三遍: 创建工程后,一定要进入到该工程所在的路径!


    Step 2: Create parent and child components.

    ng g c parent
    ng g c parent

    说明:
    (1)此时,Angular APP 还在运行中,我们要执行新的命令了,如何退出呢?—— Ctrl+C
    创建组件: g: generate ; c :component
    (2)虽然创建了两个component,因为还没有关联起来,即便运行,其结果也不会有什么变化。

    APP 的入口是 app.component.html ,在入口文件中,添加以下代码:

    <div style="text-align:center">
      <h1>
        Welcome to {{ title }}!
      </h1>
      <app-parent></app-parent>
    </div>
    

    说明:
    <app-parent></app-parent> 这个位置,是预留给 parent.component.html 的。

    Step 3: Define HTML for parent component.

    在 parent.component.html 中,添加以下代码:

    <h3>Parent Component</h3>
    <label>Bitcoin price</label>
    <input type="text" />
    <p>Value of child component is: </p>
    

    此时,再来运行,看到的首页变化了。 parent.component.html 文件加载了进来,显示如下:

    image.png

    思路: 在parent页面上输入文字, 在child 页面上显示文字。 并且, parent 与 child 在同一个页面上。所以,需要在 parent.component.html 中,引入 <app-child>

    首先,在child.component.html 文件中,添加以下代码:

    <h3>Child Component</h3>
    <label>Child Component</label>
    <input type="text" />
    <p>Value of parent component is: </p>
    

    接着, 在parent.component.html 文件中,引入<app-child>
    。代码如下:

    <h3>Parent Component</h3>
    <label>Bitcoin price</label>
    <input type="text" />
    <p>Value of child component is: </p>
    <app-child> </app-child>
    

    再来运行下,结果如下:


    image.png

    组件之间的传值,就要开始了!

    Step 5: Use Input to display parent component value

    @Input 粉墨登场!

    详情参考: @Input的应用

    Decorator : 修饰符
    A decorator is a function that is invoked with @ prefix and followed by class, method, property.
    例如: @Input()

    踩“坑”开始,请注意!!

    在 parent.component.html 文件中,修改代码如下:

    <input type="text" #pcomponent  (keyup)="0"/>
    <app-child [PData]="pcomponent.value"></app-child>
    

    说明:

    想获取 <input> 里面的值,怎么办?
    简单方法: 设置 <input> 的 reference (参考), 注意写法:
    #pcomponent

    再将该值,传给 child 页面。方法是:

    <app-child [PData]="pcomponent.value"></app-child>

    把 <input> 的值,传给一个变量 PData 。 注意, 加上 [ ], 起到“插补”的作用。

    在 child.component.html 文件中,添加代码:

    export class ChildComponent implements OnInit {
    
      @Input() PData: string;
      constructor() { }
    
      ngOnInit() {
      }
    
    }
    
    

    说明,特别注意:

    @Input() PData: string;

    @Input() 是一体的,不能分开。
    PData 是一个变量,这个变量来自 parent.component.html 的设定

    这时候,再来运行,看到如下结果:

    image.png

    如果没有出现你期望的结果,可能出现的“坑”,如下:

    “坑”(一):
    parent.component.html 中,特别注意这一行代码:

    <app-child [PData]="pcomponent.value"></app-child>

    [PData]="pcomponent.value" 必须写在 <app-child> 里面,切不可写在标签的之间:
    <app-child> [PData]="pcomponent.value" </app-child>

    “坑”(二):

    [PData]="pcomponent.value" 的赋值必须是一个变量。 简单的直接赋值是不可以的。 不可以这样写:
    [PData]="test data"

    说明:
    Angular 5.X 传值的玄妙之处就在于此。 [ ] 插补(interpolation)的用法。 如果还没理解,先跳过去,记住它的用法就可以了。

    Step 6: Pass value from child to parent component.

    思路:在child 中创建一个 Event, 通过 @Output 修饰符,供 Parent 调用;

    parent 无法获取到child,所以 parent 监听 child 的事件,当事件触发时,把child 的值传给 parent。

    在 child.component.html 中,添加代码:

    <h3>Child Component</h3>
    <label>Child Component</label>
    <input type="text" #ccomponent (keyup)="onChange(ccomponent.value)"/>
    
    <p>Value of parent component is: {{ PData }}</p>
    
    

    在 child.component.ts 中,添加代码:

    import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
    
    @Component({
      selector: 'app-child',
      templateUrl: './child.component.html',
      styleUrls: ['./child.component.css']
    })
    export class ChildComponent implements OnInit {
    
      @Input() PData: number;
      @Output() childEvent = new EventEmitter();
      constructor() { }
      onChange(value) {
        this.childEvent.emit(value);
      }
    
      ngOnInit() {
      }
    
    }
    

    代码解读:
    (1)在 ts 文件中声明一个 onChange 方法,并在 html 的 <input> 标签中调用 onChange 方法。

    (2) 为了让 parent 监听 child的事件,通过 @Output() 来声明。
    @Output() childEvent = new EventEmitter();
    这时候, parent 就可以监听 childEvent 事件了。要注意,这个事件是可以传参的。 具体传什么参数呢?

    this.childEvent.emit(value);

    传的是这个value。就看给这个参数输入什么了。

    接下来, 在 parent.component.html 文件中,绑定这个事件和参数,如下:

    <app-child [PData]="pcomponent.value" (childEvent)="CData=$event"></app-child>

    同时,在 parent.component.ts 中,声明一个变量:

    // parent.component.ts
    public CData: number;
    

    在 parent.component.html 中,显示 child的输入值:

    // parent.component.html
    <h3>Parent Component</h3>
    
    <label>Parent Component</label>
    <input type="text" #pcomponent (keyup)="0"/>
    
    <p>Value of child component is: {{ CData }}</p>
    <app-child [PData]="pcomponent.value" (childEvent)="CData=$event"></app-child>
    

    代码解读:

    为什么要声明 CData 这个变量呢? 套路是: 先赋值给一个变量,然后,在其他地方,调用这个变量。 很通俗吧!

    运行结果:

    image.png

    相关文章

      网友评论

        本文标题:Angular 5.X 学习笔记——component之间的数据

        本文链接:https://www.haomeiwen.com/subject/uxrlkftx.html