angular学习记录

这篇博客详细记录了Angular的学习过程,从项目文件解析、组件和模块的创建,到事件绑定、服务、路由、HTTP数据获取以及错误处理等多个核心概念。涵盖了*ngFor、*ngIf、事件绑定、属性绑定、服务、Observable、路由配置、HttpClient的使用和错误处理等关键知识点,是Angular开发者的重要参考资料。
摘要由CSDN通过智能技术生成

1  angular项目文件解析

创建一个angular项目ng new demo,会比较慢,等等

组件可以理解为一段带有业务逻辑和数据的html

2  组件文件的解析

组件控制屏幕上被称为视图的一小片区域。组件通过一些由属性和方法组成

//从angular核心库导入Component装饰器
import { Component } from '@angular/core';
//为组件类加上@Component装饰器。

//它是一个装饰函数。用于为该组件指定angular所需的元数据(metadata)
//元数据:angular需要知道如何把应用程序的各个部分组合到一起,以及该应用需要那些其他文件和库
@Component({
  selector: 'app-root',//组件的选择器(css元素选择器),也可以写成.app-root那么在父组件就是class写法,或者[app-root]
  //用来在父组件的模板中匹配 HTML 元素的名称。<app-heroes></app-heroes>
  //写法不同在父组件的写法就不同

  templateUrl: './app.component.html',//组件模板文件的位置
  
  styleUrls: ['./app.component.less']//组件私有css样式表文件的位置
  // 也可以写成css样式的'.css{color:red}'
})

//始终要export这个组件类,以便在其它地方导入它
export class AppComponent {
  title = 'Tour of Heroes';
}

@Component:组件装饰器:用来告知angular框架如何处理一个TypeScript类

Component装饰器包含多个属性,这些属性的值叫做元数据,Angular会根据这些元数据的值来渲染组件并执行组件的逻辑

Template:我们可以通过组件自带的模板来定义组件的外观,模板以html的形式存在

装饰器和模板还有控制器是组件的必备要素!!

3  模块文件的解析

Angular应用是模块化的,它拥有自己的模块化系统,称为NgModule,一个Ngmodule就是一个容器。每个angular应用都至少要有一个NgModule类,也就是根模块,一般习惯命名为AppModule

模块也需要装饰器来修饰,叫@NgModule 

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';

import { HeroesComponent } from './heroes/heroes.component';
//声明,每个组件都必须声明在(且只能声明在)一个NgModule中,但是可以导出给多个模块使用。 典型应用场景就是shared.module
// 如果是通过ng generate component heroes(简写ng g c 名字)命令创建的组件,那么会自动帮我们声明好了

//这里是该应用所需外部模块的列表
@NgModule({//@NgModule装饰器
  declarations: [//这里声明了应用中的所有组件(这里只能声明组件,指令,管道)
    AppComponent,
    HeroesComponent
  ],
  imports: [//导入表,声明该模块所依赖的模块
    BrowserModule,
    FormsModule,
    AppRoutingModule
  ],

  // 默认情况下是空的,本模块向全局服务中贡献的那些服务的创建器
  providers: [],

  // 声明模块的主组件是什么,只有根模块才应该设置这个 bootstrap 属性
  bootstrap: [AppComponent]
})
export class AppModule { }

4  组件和模块的关系

|-模块

   |-组件1

       |- html模板(only one)

       |- css样式表(可多个)

   |-组件2

      ....省略

5  *ngFor和*ngIf和(click)

6  事件绑定

事件绑定语法由等号左侧括号内的目标事件名和右侧引号内的模板语句组成的

<button (click)=’name()’></button>

这里目标事件名是click。模板语句是name()

自定义事件:

该指令会创建一个eventEmitter并将其对外暴露为属性

然后该指令调用eventEmitter.emit(data)发出事件,传入消息数据,该消息数据可以是任何东西

父指令通过绑定到该属性来监听事件,并通过传入的$event对象接受数据

7  属性绑定

绑定类型(按数据流的方向):从数据源到视图,从视图到数据源,双向

从数据源到视图:插值({{ name }}),属性([ ]=’ ’),Attribute(( bind-name )),Css类,样式

从视图到数据源:事件( ( name )=’ ’或on-name=’ ’ )

双向:[( name )],bindon-name=’ ’

 

HTML的attribute和DOM的property(两个翻译起来都是属性)

Attribute:唯一作用的初始化元素和指令的状态

Property:模板绑定使用的是property和事件,而不是Atteibute,编写数据绑定时,你只是在和目标对象的DOM property和事件打交道

 

从Attribute页面导航到Property页面:

A <input>

              <input type="text" value="Sarah">

              HTML 的 value 这个 attribute 指定了初始值;DOM 的 value 这个 property 是当前值

B 禁用按钮

              Attribute: <button disabled>Test Button</button>

              property :<input [disabled]="变量? true : false">

8  css样式的绑定:[class:样式]=true

9  父子指令以及组件之间共享数据

可以用@input()和Output()来实现

@input()允许父组件更新子组件中的数据

@Output允许子组件像父组件发送数据

10  @input()装饰器

用法:@input()  name :string(name 的值来自父组件)

  • 装饰器首先要import,然后@input()  name :string
  • 下一步就是配置父组件,在父组件的模板中绑定该属性。把子组件的name属性绑定 到父组件的selectedHero属性上
  • 在父组件类中为selectedHero指定一个值
<app-hero-detail [name]="selectedHero"></app-hero-detail>
// [hero]属性绑定把父组件的selectedHero的值传到子组件的hero属性中,这时		候子组件就可以使用到父组件传过来的值了

11  @Output()装饰器

12 双向绑定

Angular的双向绑定语法是方括号和圆括号的组合[( )]。[ ]进行属性绑定,( )进行事件绑定

<input [(ngModel)]="hero.name" placeholder="name"/>

使用EventEmitter:它是一个帮你实现观察者模式的对象,也就是说,它是一个管理一系列订阅者并向其发布事件的对象。

首先得创建一个服务,import  EventEmitter,在在构造函数里面定义一个发射事件

public eventEmit:any;
  constructor() { 
    // 定义发射事件
    this.eventEmit = new EventEmitter
  }

B  需要把服务注册到根模块中

C  把数据通过eventEmit.emit()发送出去

 userList = 'aaa'  
emitFun(){
    this.emitService.eventEmit.emit(this.userList)
  }

D 在通过eventEmit.subscribe(value){}订阅到刚刚发出的数据

 sonData = ''
  ngOnInit(): void {
    this.emitService.eventEmit.subscribe((value:any)=>{
      alert("我接受到了发送的数据啦!")
      this.sonData = value
    })
  }

13  服务(service)

有点像vuex的感觉,但是在使用的时候,服务需要在根模块@NgModule下的providers中注册,在组件中使用的时候也需要注入

组件不应该获取或者保存数据,应该聚焦于展示数据,而把数据访问的职责委托给服务

这就是服务的由来~服务是在多个“互相不知道”的类之间共享信息的好办法

Angular项目把需要的数据都封装在一个盒子里面,这个盒子就是 Injectable装饰器。

import { Hero } from './hero';
import { HEROES } from './mock-heroes';

这里是把数据引入到服务上,然后通过HeroService类里面的

getHeroes(): Hero[] {
    return HEROES;
  }

在把数据返回出去

 

a 要想在组件中使用HeroService类,必须要先把它注册到依赖注入系统中去。

b 或者提供给服务商(某种可用来创建或交付服务的一个东西),然后服务商通过实例化

   HeroService类,来提供服务。

c 默认情况下,angular服务是已经注册好在root根注入器里面的,如下:

@Injectable({
  providedIn: 'root'
})

注册好了之后,就可以使用HeroService类了。 首先在需要用到数据的组件文件里面引入HeroService类

import { HeroService } from '../hero.service'; 

在构造函数中添加一个私有的heroService,其类型为HeroService。在angular创建组件类的新实例时,它会通过查看该组件类的构造函数,来决定该组件依赖哪些服务或者其它依赖项。

constructor(private heroService: HeroService) { }

然后创建一个方法,以从服务中获取到这些数据

 getHeroed():void{
    this.heroes = this.heroService.getHeroes()
  }

然后就可以在ngOnInit()中调用啦~(但这不是最佳实践)

14  Observable可观察的数据(异步)

Observable是RxJS库中的一个关键类。现在可以用RxJS中的of()函数来模拟从服务器返回数据

a 首先还是导入Observable和Of

b  然后getHeroes()改成这样

  getHeroes(): Observable<Hero[]> {
    return of(HEROES);
  }

这里的of(HEROES)会返回一个Observebl<Hero[]>,它会发出单个值,这个值就是这些模拟英雄的数组

然后getHeroes()里面就应该是这样的(异步)

  getHeroes():void{
    this.heroService.getHeroes()
    .subscribe(heroes => this.heroes = heroes)
  }

15 依赖注入

依赖注入包含三个角色:调用者(client),服务(service),注入者(injector)

一个依赖是一个被其它对象调用的对象(服务)

注入则是将被依赖的对象(service)实例传递给依赖对象的行为

16  ngOnInit和constructor

ES6引入了class类的概念,创建的每一个class类,都会有一个constructor()    方法,该方法是一种用于创建和初始化class创建的对象的特殊方法--构造函数方法。

17  路由

angular Route有两个属性path(路径)和component(导航到该路由时,路由器 应该创建的组件)

{ path: 'heroes', component: HeroesComponent }
//这里就是导航到/heroes的时候,渲染的是HeroesComponent组件

{ path: '', redirectTo: '/dashboard', pathMatch: 'full' }
//而当我们启动应用时,需要把空路径重定向到/dashboard

{ path:'detail/:id' , component: HeroDetailComponent }
//这里就是在路径后面加了id,和vue都是一样的。这里的冒号表示:id是一个占位符

路由的使用:

A  首先要安装路由ng generate module app-routing --flat --module=app  有的路由安装会在项目创建的时       候就问你需不需要安装了,如果当时安装了这时候就不需要安装了

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

// 这里就是我们写路由的地方啦~
const routes: Routes = [];
@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

B  然后设置主页路由,重定向去index

{path:'', redirectTo:'/index', pathMatch: 'full'}

C  这时候我们的index还没有路由,于是我们需要设置index路由指向

{path:'index', component:IndexComponent}

D  这时候我们路由设置基本好了,还需要添加路由出口,才能看到路由所要显示的视图<router-outlet> 会      告诉路由器要在哪里显示路由的视图。到这里路由就安装完毕啦~

子路由:

{path:'index', component:IndexComponent,
    children:[
      {
        path:'child-a',component:ChildAComponent
      },
      {
        path:'child-b',component:ChildBComponent
      }
    ]
  },

惰性加载:

Angular只会在需要时才加载这些模块,而不是在应用启动时就加载全部,而默认情况下ngModule都是急性加载的,所以。。。

A 首先我们要创建一个包含路由目标组件的特性模块 

   ng generate module load1 --route load1 --module app.module  

B 然后在路由文件中,使用loadchildren代替component进行配置

 { path: 'load11', 
    loadChildren: () => import('./load11/load11.module')
    .then(m => m.Load11Module) 
  },

C 这就可以实现路由的懒加载啦~~~

18  routerLink

点击这个a标签路由就会跳转到/heroes路径下:如果跳去子路由则前面不需要加/

<nav>
    <a routerLink='/heroes'>Heroes</a>
</nav>

这里是在复写器中使用angular的插值绑定来把当前的hero.id插入到每个routerLink中。和上面路由定义里面的:id配套。这样就可以实现对于的id跳转到对应的页面

<a *ngFor = "let hero of heroes" class="col-1-4"
        routerLink="/detail/{{hero.id}}">
        <div class="module hero">
            <h4>{{hero.name}}</h4>
        </div>
    </a>

引入ActivatedRout,在构造函数中注入保存为私有变量,获取到路径上的id

import { ActivatedRoute } from '@angular/router';
// ActivatedRoute 保存着到这个 HeroDetailComponent 实例的路由信息,如id

要获取路由上面的id,需要先引入ActivatedRoute,这个保存着对应实例的路由信息

this.activatedRoute.params.subscribe(params=>{
     this.params = params;
  })

这里的params就是获取到的路由id啦~。因为详情页需要用到它,所以定义的时候要定义成pablic,如下:

public params:any = 11;
ngOnInit(): void {
    this.getData()
  }
  getData(){
    this.activatedRoute.params.subscribe(params=>{
      this.params = params;
    })
  }

19  从服务器获取数据HttpClient

首先HttpService通过http请求获取英雄数据。要让HttpService随处可用,添加到根模 块中去d

其次要在heroService里面注入HttpService和HttpHeaders

然后就可以获取到数据啦~

getHeroes(): Observable<Hero[]> {

    return this.http.get<Hero[]>(this.heroesUrl)

 };

这时候数据就会从模拟服务器被成功读取了(http.get()):heroService.getHeroes()

20  HttpClient 的方法返回单个值

具体到这次 HttpClient.get() 调用,它返回一个 Observable<Hero[]>,也就是“一个英雄数组的可观察对象”。在实践中,它也只会返回一个英雄数组

21  错误处理(catchError())

首先还是老规矩需要import进来。然后我们这里需要用到pipe()方法来扩展observe的结果

 getHeroes(): Observable<Hero[]> {
    return this.http.get<Hero[]>(this.heroesUrl)
    .pipe(
      catchError(this.handleError<Hero[]>('getHeroes',[]))
    )
  };

22 窥探Observable

可以通过tap()来记录各种操作,并通过log()方法往页面底部发送一条消息

p(_ => this.log('fetched heroes')),

23 在ng g c 创建一个组建的时候经常会报错

More than one module matches. Use the skip-import option to skip importing the component into the closest module or use the module option to specify a module.

这时候可以指定模块,用ng g c testSoon --module=app,指定创建在app模块下

24 管道

用来格式化我们的数据,比如字符串,货币金额,日期和其它显示数据。可以在模板表达式中用来接受输入值并返回一个转换后的值

常用的管道如下:

DatePipe:根据本地环境中的规则格式化日期值,对于内置的DatePipe,它的名字的date

串联管道:一个管道的输出值是下一个管道的输入,如下(先把日期转换在转成大写):

<P>之后:{{ birthday | date:'fullDate' | uppercase }}</P>

自定义管道:要把类标记为管道,需要把@Pipe装饰器应用到这个类上,管道类名是UpperCamelCase(类名的一般约定)相应的name字符串是camelCase的

   A  首先需要创建一个管道文件.Pipe.ts,ng g pipe name

   B  这就是创建好的pipe文件,创建好之后需要声明在根模板里面的,一般通过命令行   的方式会自动帮         我们注册进根模板啦

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'multiple'//这就是管道的名字
})
export class MultiplePipe implements PipeTransform {

//args是管道的参数,可以为空
  transform(value: unknown, ...args: unknown[]): unknown {

    return null;
  }
}

C 接下来就可以在视图中使用啦

自定义一个

transform(value: any, args: any): any {
    if(!args){
      args = 1
    }
    return value * args;
  }

//使用
<p>之后:{{num | multiple : '2'}}</p>

注:管道的操作符要比三目运算符(a ? b : c)的优先级高

25 指令

属性指令:会监听并修改其它HTML元素和组件的行为。它们通常被应用在元素上,就像HTML属性一样,所以称为属性指令

比较常见的属性指令:

     NgClass:添加和删除一组css类

     NgStyle:添加和删除一组HTML样式

     NgModel:将数据双向绑定添加到HTML表单元素

结构型指令:它们塑造或者重塑DOM的结构,这通常是通过添加、移除和操纵它们所添加到的宿主元素来实现,常见的有:

     NgIf:从模板中创建或销毁子视图

     NgFor:为列表中的每个条目重复渲染一个节点

     NgSwitch:一组在备用视图之间切换的指令

26 事件绑定

$event和事件处理语句:事件对象的形态取决于目标事件。如果目标事件是原生DOM 元素事件,\$event就是 DOM 事件对象,它有像 target 和 target.value 这样的属性

27  表单

响应式表单和模板驱动表单

(): Observabl

常用表单基础类:

     FormControl:实例用于追踪单个表单控件的值和验证状态

     FormGroup:用于追踪一个表单控件组合值和状态

     ForArray:用于追踪表单控件数组的值和状态

     ControlValueAccessor:用于在angular和FormControl实例和原生DOM元素之间创建一 个桥梁

建立响应式表单:

     对于响应式表单,首先通过输入元素上的[formControl]指令,然后这个指令会通过内部值访问器来把显        式创建的FormControl实例与视图联系起来

创建过程如下

//需要在根模块中导入FormsModule和ReactiveFormsModule 才能用表单
import { FormsModule , ReactiveFormsModule } from '@angular/forms';


//需要在要添加表单的组件中,导入FormControl,并实例化它
//导入:
import { FormControl } from '@angular/forms';
//实例化:
 fromFrom = new FormControl('');


//接下来就可以用[ formControl ]指令啦~
 <input type="text" [formControl]="fromFrom">

建立模板驱动表单:

     顾名思义就是HTML模板+表单专业指令来构建表单

     对于模板驱动表单,是指令ngModel为指定的表单元素创建并管理一个FormCobtrol实例,我们没有           FormControl实例直接编程访问,而是对表单模型的间接访问。

模板驱动表单依赖的几个指令: NgModule NgForm NgModelGroup

<form #modelForm="ngForm">
/* 
#是模板引用变量。这里是在当前文档作用域创建了一个modelForm变量,来表示这个组件本身,可以在外部调用这个组件的对外方法和对外变量
模板引用变量的范围是整个模板,后面的ngForm大体不用管。
涉及到了一个问题用#modelForm="ngForm"和[ngFormModel]="modelForm"区别:
第一种是“模板驱动”形式:angular将向该表单添加隐式指令,并且在模板中主要以声明性方式添加验证器,因此名称为“模板驱动”。
第二种是“模型驱动”形式:在这里我们不在模板上声明验证器,而是声明控件名称。然后所有验证逻辑都通过代码而不是在模板中声明。响应式表单
*/

<label>用户名:</label>
<input name="name" placeholder="用户名" type="text" required minlength="4" [(ngModel)]="model.name" #name="ngModel">
//这里是你可以通过把 ngModel导出成局部模板变量来查看该控件的状态。 这里就是把NgModel导出成了一个名叫name的变量
 /* 
这里是只有在name为错误和该控件被标记为dirty或被标记为touched时候才显示
dirty(脏):当用户在被监视的字段中修改该值时,控件就会被标记为脏
touched(已接触):当用户在表单控件失去焦点时,该控件就会被标记为已接触
大体其实不用多管,这是固定这样写的

当表单控件中的值发生变化时,angular就会进行验证,并生成一个验证错误的列表,对应着invalid 状态,所以下面这里就是name有错误的时候
*/
    <div *ngIf="name.invalid && (name.dirty || name.touched)" class="alert-danger">
        <div *ngIf="name.errors.required">
            用户名不能为空
        </div>
        <div *ngIf="name.errors.minlength">
            用户名长度不能少于4个字符
        </div>
    </div>
    <button type="submit" [disabled]="modelForm.invalid">提交</button>
    <button type="button" (click)="modelForm.resetForm({})">重置</button>


    <div *ngIf="modelForm.submitted">
        已提交:
        <p>用户名:{{ modelForm.value.name }}的用户!</p>
        <p>其它爱好:{{ modelForm.value.other }}</p>  
    </div>
</form>

表单中的数据流

响应式的数据流:在响应式表单中,视图中的每个表单元素都直接链接到一个FormControl实例(表单模型),从视图到模型的修改以及从模型到视图的修改都是同步的,而不依赖于UI的渲染方式。

在模板驱动表单中验证输入:

每当表单控件中的值发生变化时,angular就会进行验证,并生成一个验证错误的列表,你可以通过把ngModel导出成局部模板变量来查看该控件的状态

<input type="text" [(ngModel)]="formHide"/>
    <input id="name" name='name' class="form-control" 
        required minlength="4" appForbiddenName='bob'
        [(ngModel)]='hero.name' #name='ngModel' />
    <div *ngIf="name.invalid && (name.dirty || name.touched)"
        class="alert alert-danger">
        <div *ngIf="name.errors.requied">
            名字不能为空
        </div>
        <div *ngIf="name.errors.minlength">
            名称必须至少4个字符
        </div>
        <div *ngIf="name.errors.forbiddenName">
            名字不能是Bob
        </div>
</div>
    <!-- 自定义的验证器指令forbiddenName
    #name='ngModel'把ngModel导出成了一个名叫name的局部变量
    ngModel把自己控制的FormControl实例属性映射出去
    让你能在模板中检查控件的状态
    div元素的*ngIf展示了一组嵌套的消息
    但是只在有“name”错误和控制器为dirty或者touched时才出现
    每个嵌套的div为其中一个可能出现的验证错误显示一条自定义消息
    比如required、minlength和forbiddenName -->

28  Rxjs

Subject(主体):相当于EventEmitter,并且是将值或事件多路推送给多个Observer的唯一方式

Observable(可观察对象):表示一个概念,这个概念是一个可调度的未来值或事件的集合

Observer(观察者):一个回调函数的集合,它知道如何去监听由observerble提供的值。

Subscription(订阅):表示observable的执行,主要用于取消observable的执行、

Operators(操作符):采用函数式编程风格的纯函数,使用像map,concat等这样的操作符来处理集合。

操作符:操作符是基于可观察对象构建的一些对集合进行复杂操作的函数

RxJS的使用:

A 在服务里面实例化一个主体。也就是我们要将这个主体推给多方的。。。这个主体就是 可观察对象的主体。这个可观察对象的主体赋值给count$(一般可观察对象都会在后 面标识一个$,方便看)。其它组件就订阅到这个count啦,这就是前三句的作用

注:而这里有一个要注意的点,就是这里用的是asObservable()作用是为了防止订 阅者改变这里的值,也就是主体传过来的值是不能被随意改变的,除非有特殊要求另外 讲。

这样当其它组件调用到了asObservable()的值的时候,不能使用.next()发 射值出去,这样保证了主体值的安全性。

_count = 0
private count = new Subject<number>();
//Subject1是一个特殊的Observable,它允许将值多播给多个观察者
count$ = this.count.asObservable()

如果组件想要修改值,应该给服务添加一个方法,然后其它组件调用这个方 法来修改这个Subject的值。

onAdd() {
    this._count++;
    this.count.next(this._count);
  }

到这里服务这里的动作就完成了从主体到可观察对象

B 这里就是订阅啦,观察者订阅可观察对象就是一个subscribe

  count$: Subscription;

接下来就可以对订阅到的值进行自己的处理啦

this.emitService.count$.pipe(
      throttleTime(1000),
      map(count => ++count),
    ).subscribe(res => {
      console.log('child2', res);
    })

30 动态组件

  @ViewChild('vc', { read: ViewContainerRef }) vc: ViewContainerRef;
 /*这里是一个描点,告诉angular要把组件插入到什么地方
    属性装饰器,用于配置一个视图查询,变更检测器会在视图的Dom中查找能匹配上该选择器的第一个元素或指令
如果你想插入新的组件或模板,你需要告诉angular,哪里去放置这个元素ViewContainerRef 就是这个作用,一个你可以将新的组件作为其节点的DOM元素(容器)
这里vc就是宿主元素
我们可以使用ViewChild装饰器来收集任何我们视图上的元素,并将其当作ViewContainerRef。
*/
  @ViewChild('tpl') tpl: TemplateRef<any>;
<ng-content #vc></ng-content>
/*
这个组件能够接受外部投射进来的内容,也就是除了组件自己本身的内容,还呈现了外部嵌入的。它还支持一个select属性,可以在特定的地方投射相应的内容;如select=".demo2",这里就是代表它对应的外部内容样式的demo2。select的值不能设置为动态的
简单来说就类似路由出口router-outlet一样
*/

<ng-template #tpl>
    <br />
    <span>我是一个模板内容</span>
    <span>我是一个模板内容</span>
    <br />
</ng-template>
//这里的ng-te是用于定义模板渲染HTML,定义的模板不会直接显示出来,所以这里是借助了上面的ng-con显示出来的

<button (click)="insert()">插入</button>
 insert() {
    let view = this.tpl.createEmbeddedView(null);
    this.vc.insert(view);
  }

这里有一个需要注意的:

/*
ng-container 主要是用来当一个容器用。只是一个单纯的特殊的tag。可以包裹任何元素,包括文本,但本身不会生成元素标签,也不会影响页面样式和布局。简单理解就是一个逻辑容器,用来做一些逻辑处理的,它的一个重要作用就是和ng-template一起用,还有我们知道ngFor和ngIf不能处在一个元素上,为了达到一样的效果就可以用上它啦
*/
<ul>
    <ng-container *ngFor="let item of list;let index=index">
        <li *ngIf="index%2 === 0">
            {{"index is " + index + " value is " + item}}
        </li>
    </ng-container>
</ul>

/*
ng-content:用来投影来自父组件的内容。它是内容映射指令(也叫内容嵌入),方便定制可复用的组件,相当于在这里留了一个位置,方便把相应的内容放到这个位置上来。
*/
//左侧没有 [] 的一律当成字符串传入
    [rowData]="rowData"
// 传入变量,rowData 是什么类型则传入什么类型
    [pinnedBottomIdKey]="'stockName'"
// 传入变量,'stockName' 是一个常量字符串
    pinnedBottomIdKey="{{ stockName }}"
// 传入字符串,类似调用 stockName.toString()
    pinnedBottomNameKey="stockName" 
// 传入字符串,常量字符串

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值