A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 AreYouGlad 于 2018-1-12 19:11 编辑

查看更多精彩前端资源



特殊属性指令
  • 因为元素的classstyle都是复合型功能的属性
  • 为了能够更精细的控制他们, Angular专门设计了特殊的指令与规则

class控制单个控制
  • 如果只控制一两个class, 可以使用这种方式
  • 指令语法:[class.css类名]="表达式"

[HTML] 纯文本查看 复制代码
.btn-red {
    color: red;
}


<!-- 通过isLong控制单个class的添加与移除, 这里点击按钮的时候改用直接书写表达式的方式进行值的修改 -->
<button [class.btn-red]="isLong" (click)="isLong = !isLong">点击添加移除样式</button>

批量控制
  • 如果要批量控制多个class, 可以使用这种方式
  • 指令语法: [ngClass]="表达式"
  • 因为这里会同时控制多个样式, 就不再编写css了, 而是通过调试工具查看class是否正常添加或移除

[JavaScript] 纯文本查看 复制代码
<!-- 通过btnClasses控制多个class的添加与移除 -->
<button [ngClass]="btnClasses">批量添加控制class</button>

export class AppComponent {
  // 批量控制按钮的class, 这里使用随机数的方式测试控制是否有效
  btnClasses = {
    a: Math.random() > 0.5,
    b: Math.random() > 0.5,
    c: Math.random() > 0.5,
    d: Math.random() > 0.5
  };
}

style控制单个控制
  • 如果只控制一两个style样式, 可以使用这种方式
  • 指令语法:[style.样式名]="表达式"

[JavaScript] 纯文本查看 复制代码
<!-- 单个style控制 -->
<section [style.color]="sectionColor" [style.fontSize]="sectionSize">我是不一样的烟火</section>

export class AppComponent {
        // 单个样式控制
        sectionColor = 'pink';
        sectionSize = '24px';
}

批量控制
  • 如果要批量控制多个style, 可以使用这种方式
  • 指令语法: [ngStyle]="表达式"

[JavaScript] 纯文本查看 复制代码
<!-- 多个style控制 -->
<section [ngStyle]="sectionStyle">我是不一样的烟火</section>

export class AppComponent {
        // 多个样式控制
    sectionStyle = {
            color: 'blue',
            fontSize: '30px',
            fontWeight: 'bold'
    };
}

管道操作符
  • 管道在AngularJS中称为过滤器, 它的作用是格式化数据
  • 语法:{{ 数据 | 管道函数:参数(可选) }}, 数据与管道函数中间使用的符号叫管道操作符

预览uppercase
  • 大写转换

[HTML] 纯文本查看 复制代码
<!-- 为了演示便利, 这里的Angular加了引号就是一个普通字符串, 如果不加就是数据绑定 -->
<p ngNonBindable>{{ 'Angular' | uppercase }}</p>

lowercase
  • 小写转换

[HTML] 纯文本查看 复制代码
<!-- 管道可以连续调用多个, 下面的执行过程是先转大写再转小写, 最终输出小写的angular -->
<p ngNonBindable>{{ 'Angular' | uppercase | lowercase }}</p>

number
  • 数字格式化
  • 可选参数: '最少整数位.最少小数位-最多小数位'
  • 备注: 小数在截取时会四舍五入

[JavaScript] 纯文本查看 复制代码
<div style="border: 4px solid red;">
  <!-- 至少4位整数0位小数 => 0,365 -->
  <p>{{ 365 | number: '4.0' }}</p>

  <!-- 至少1位整数4位小数, 小数至多6位 => 3.141593-->
  <p>{{ 3.14159265 | number: '1.4-6' }}</p>

  <!-- 至少1位整数4位小数, 小数至多6位 => 3.1400 -->
  <p>{{ 3.14 | number: '1.4-6' }}</p>
</div>

date
  • 日期格式化

[JavaScript] 纯文本查看 复制代码
<!-- 日期格式化为年月日 -->
<p>{{ currentTime | date:'yyyy-MM-dd' }}</p>

export class AppComponent {
  // 日期管道测试
  currentTime = Date.now();
}

json
  • 对象序列化为字符串

[HTML] 纯文本查看 复制代码
<!-- 把之前的城市数组转为JSON输出 => [ "北京", "上海", "广州", "深圳" ] -->
<p>{{ cityList | json }}</p>

管道链
  • 可以将多个管道连接在一起,组成管道链对数据进行处理

[HTML] 纯文本查看 复制代码
<p>{{ 'Angular' | slice:0:3 | uppercase }}</p>

组件化
组件化概念
  • 组件化是一种开发模式, 它把页面上每个独立的可视/可交互区域视为一个个组件
  • 每个组件都是独立可复用的, 页面只不过是组件的容器,通过组件的自由组合形成功能完整的界面

组件化好处
  • 组件都是单一职责的, 每个组件实现一个功能, 基本上需求有变更只需迭代更新对应组件即可
  • 组件具有高内聚低耦合的特性, 不会对其他组件造成过多干扰, 适合长久维护
  • 使用组件的方式开发, 会让我们的HTML代码结构更加清晰, 提高可读性

代码组织方式
  • Angular组件由多个文件构成, 所以每个组件对应一个工程目录,组件所需的各种资源都在这个目录下就近维护
  • 当不需要某个组件,或者想要替换组件时,可以整个目录删除/替换

创建组件
  • cli工具提供了自动创建angular文件的命令, 可快速创建文件
  • 使用工具创建时需保证src/app/app.module.ts文件里没有任何注释, 否则会有问题

创建公共header组件
  • 约定: app目录下存放页面级别组件, app/components目录下存放页面中的公共组件
  • 运行命令创建header公共组件: ng g component components/header

组件内容详解
[JavaScript] 纯文本查看 复制代码
import { Component, OnInit } from '@angular/core';

@Component({
    selector: 'app-header',
    templateUrl: './header.component.html',
    styleUrls: ['./header.component.css']
})
// 这个类实现了Oninit接口, 该接口定义了一个Oninit方法, 数据初始化的代码一般会写在这里, 比如发送请求获取数据
export class HeaderComponent implements OnInit {
    constructor()
    ngOnInit() {}
}

组件的使用方式
  • 每个组件定义时都有一个selector元数据, 元数据就是某种东西的固有特性
  • 每个组件就是一个自定义标签, 标签名为selector元数据, 那里使用组件就在那里加上自定义标签即可
  • 打开app.components.html文件, 加入下面的html代码然后查看浏览器效果

[HTML] 纯文本查看 复制代码
<app-header></app-header>

父子组件通讯
  • 在每个独立的组件间想互相通讯,就要使用特定的修饰符来进行组件中的通讯

父传子
  • 数据父传子需要两步操作

第一步
  • 在父组件调用子组件的时候通过属性指令语法传入数据
  • 在父组件app.component.html中写入如下html代码

[HTML] 纯文本查看 复制代码
<app-header [title]="titleData"></app-header>

第二步
  • 子组件里导入Input装饰器, 然后定义相同的属性, 使用Input装饰器进行装饰即可自动接收来自父的数据
  • 在子组件app/components/header.component.ts中写入如下html代码

[JavaScript] 纯文本查看 复制代码
import { Component, OnInit ,Input } from '@angular/core'; // 导入Input装饰器

export class HeaderComponent implements OnInit {
        // 这个属性名必须和父传递值所用的属性名一致
        // 使用Input装饰器装饰后即可接收来自父的数据
    @Input() title:string
    constructor() { }
    ngOnInit() { }
}

测试
  • 在子组件app/components/header.component.html中写入如下html代码

[HTML] 纯文本查看 复制代码
<h2>头部组件, 由父组件指定的title: {{ title }}</h2>

数据自动更新
  • 里的数据发生变化时, 会自动接收新的值然后重新渲染视图
  • 在父组件app.component.html中写入如下html代码, 输入文本子组件跟着更新

[HTML] 纯文本查看 复制代码
<input type="text" [(ngModel)]="titleData">
<app-header [title]="titleData"></app-header>

子传父 - 方式一
  • 先创建一个新的组件: 'ng g component footer', 然后进行子传父练习
  • 这种方式大概也是两步: 首先父给子传一个方法, 然后子调用这个方法给父传值
  • 备注: 这种方式在React框架里面使用比较常见

第一步
  • 在父组件里定义一个方法, 然后调用子组件通过属性绑定的方式把方法传给子法

[JavaScript] 纯文本查看 复制代码
export class AppComponent {
        parentFn(): void {
                console.log('我是来自父的方法')
        }
}

<!-- 注意[]里面的属性名是什么, 子就用什么属性名接收 -->
<app-header [fn]="parentFn"></app-header>

第二步
  • 子组件接收父组件传过来的方法, 然后在需要的时候进行调用即可传值

[JavaScript] 纯文本查看 复制代码
import { Component, OnInit, Input  } from '@angular/core';

export class FooterComponent implements OnInit {
    // 使用Input装饰器装饰后, 就会接收父传入的方法
    @Input() fn:any;

        // 当组件初始化完毕后就会调用自动这个方法
    ngOnInit() {
            // 1秒后调用来自父的方法
            setTimeou(() => {
                    this.fn();
            }, 1000);
    }
}

子传父 - 方式二
  • 先创建一个新的组件: 'ng g component aside', 然后进行子传父练习
  • 这种方式大概也是两步: 首先父监听子组件的一个自定义事件, 然后子里面在需要的时候触发这个事件进行传值
  • 备注: 这种方式在Vue框架里面使用比较常见

第一步
  • 父组件调用子组件的时候,绑定一个自定义事件 ,sonEven就是子组件的发出的自定义事件

[JavaScript] 纯文本查看 复制代码
<app-aside (sonEvent)="parentFn()"></app-aside>

export class AppComponent {
        parentFn(): void {
                console.log('我是来自父的方法')
        }
}

第二步
  • 子组件里导入Output装饰器与EventEmitter事件对象
  • 然后定义一个属性存储EventEmitter实例, 并使用Output装饰器进行装饰
  • 然后在需要的时候向外发射这个属性让父接收其值

[JavaScript] 纯文本查看 复制代码
import { Component, OnInit, Output, EventEmitter} from '@angular/core';

export class FooterComponent implements OnInit {
        // 创建EventEmitter实例, 并用output装饰器装饰
        @Output() private sonEvent = new EventEmitter<string>();

        ngOnInit() {
        // 1秒后
        setTimeout(() => {
            this.sonEvent.emit();
            console.log(123);
        }, 1000);
   }

父子通讯其他方式
  • 下面的两种方式自己阅读了解, 实际不建议这样使用, 增加了父子的耦合度

父子通讯方式1
  • 父组件通过局部变量获取子组件的引用,然后在模版里通过变量调用子组件的数据和方法

第一步
  • 父组件调用子组件的时候给子组件起个名字

[HTML] 纯文本查看 复制代码
<app-footer #footer></app-footer>

第二步
  • 父通过子组件的名字可以在模版中直接使用其属性与方法

[HTML] 纯文本查看 复制代码
<p>{{ footer.msg }}</p>
<button (click)='footer.fn()'>点击执行子组件的方法</button>

父子通讯方式2
  • 父组件通过局部变量获取子组件的引用,然后通过ViewChild装饰器提取子组件的属性与方法
  • 接下来就可以通过js的方式调用子组件的东西了

第一步
  • 父组件调用子组件的时候给子组件起个名字

[HTML] 纯文本查看 复制代码
<app-footer #footer></app-footer>

第二步
  • 父通过ViewChild装饰器提取子组件的属性与方法

[JavaScript] 纯文本查看 复制代码
import { Component, ViewChild } from '@angular/core';

export class AppComponent {
        // 提取footer子组件的属性与方法到父属性footer上
        @ViewChild('footer') footer;

        ngOnInit() {
        // 父在需要的时候调用子的属性方法
        console.log(this.footer);
    }
}

1 个回复

正序浏览
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马