基本的使用组件
注意:必须在module的declarations中声明
目录结构:
zengwe@zengwe-PC:test1$ tree -I '*node_modules*|*e2e*'
.
├── karma.conf.js
├── package.json
├── protractor.conf.js
├── README.md
├── src
│ ├── app
│ │ ├── app.component.css
│ │ ├── app.component.html
│ │ ├── app.component.spec.ts
│ │ ├── app.component.ts
│ │ ├── app.module.ts
│ │ ├── community
│ │ │ ├── community.component.css
│ │ │ ├── community.component.html
│ │ │ ├── community.component.spec.ts
│ │ │ └── community.component.ts
│ │ ├── content
│ │ │ ├── content.component.css
│ │ │ ├── content.component.html
│ │ │ ├── content.component.spec.ts
│ │ │ └── content.component.ts
│ │ ├── content-parts
│ │ │ ├── content-parts.component.css
│ │ │ ├── content-parts.component.html
│ │ │ ├── content-parts.component.spec.ts
│ │ │ └── content-parts.component.ts
│ │ ├── item
│ │ │ ├── item.component.css
│ │ │ ├── item.component.html
│ │ │ ├── item.component.spec.ts
│ │ │ └── item.component.ts
│ │ └── value
│ │ ├── value.component.css
│ │ ├── value.component.html
│ │ ├── value.component.spec.ts
│ │ └── value.component.ts
│ ├── assets
│ ├── environments
│ │ ├── environment.prod.ts
│ │ └── environment.ts
│ ├── favicon.ico
│ ├── index.html
│ ├── main.ts
│ ├── polyfills.ts
│ ├── styles.css
│ ├── test.ts
│ ├── tsconfig.app.json
│ ├── tsconfig.spec.json
│ └── typings.d.ts
├── tsconfig.json
└── tslint.json
组件的基本应用
需要被引入的组件./item/item.component
该组件的html如下
<p>
item works!
</p>
使用这个组件
<div class="demo1">
<p>app-item这个标签的名字是./item/item.component.ts中
装饰器@component selector:value中的value
</p>
<p>这个是什么也不传</p>
<app-item></app-item>
</div>
父组件向子组件传值
需要被引入的组件./value/value.component
import { Component, OnInit, Input, AfterViewInit } from '@angular/core';
@Component({
selector: 'app-value',
templateUrl: './value.component.html',
styleUrls: ['./value.component.css']
})
export class ValueComponent implements OnInit, AfterViewInit {
@Input('value') value: string;//接收'value'是html中的[value],第二个value为变量名,随意取
constructor() {
console.log('component value constructor');
console.log(this.value);
}
ngOnInit() {
}
ngAfterViewInit() {
console.log('component value ngAfterViewInit');
console.log(this.value);
}
}
传值./app.component.html
<div class="demo2">
<p>传值,父组件的值为:{{value1}}</p>
<app-value value="{{value1}}"></app-value><br>
<p>然后在value.component中@Input获取到这个值,但是这个值在组件渲染初始化后才有值,之前都是undefind</p>
<p>第二种传值。父组件的值为:{{value1}}</p>
<app-value [value]="value1"></app-value><br>
<p>第二种传值。父组件的值为:{{value1}}</p>
<input type="text" [(ngModel)]="value1">
<app-value [(value)]="value1"></app-value><br>
<p>ps:子组件内部修改值并不能影响到父组件,而父组件的值修改却修改了子组件的值,说明数据流其实是至上而下的</p>
</div>
父组件获取子组件的实例@ViewChild(就是子组件的component对象)
没写@ViewChildren的原因是这个和@ViewChild唯一区别可能就是一个获取到的是单个一个获取到的数组,@ViewChild中如果有多个相同,则只获取第一个
app.component.html
<div class="demo3">
<p>父组件获取子组件,#target为钩子,用于找到组件</p>
<app-item #target></app-item>
</div>
app.component.ts
import { Component, ViewChild, AfterViewInit } from '@angular/core';
import { ItemComponent } from './item/item.component';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements AfterViewInit {
value1= 'zengwe';
@ViewChild('target') target: ItemComponent;
ngAfterViewInit() {
//必须在页面组件初始化完成后才能得到这个值
console.log(this.target);
}
}
子组件与父组件通信@Input&@Output
app.component.html
<div class="demo4">
<p>子组件与父组件通信</p>
<p>communityEvent使用()包起来的是自定义的事件,子组件通过处罚这个事件,从而触发父组件的
callParent($event),$event这个只能这么写,callParent这个方法才能得到值
</p>
<app-community (communityEvent)="callParent($event)"></app-community>
</div>
community.component.ts
import { Component, OnInit, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-community',
templateUrl: './community.component.html',
styleUrls: ['./community.component.css']
})
export class CommunityComponent implements OnInit {
@Output('communityEvent') communityEvent: EventEmitter<any> = new EventEmitter();
constructor() { }
ngOnInit() {
}
emiteParentEvent() {
//在html使用这个组件时(communityEvent),这个括号就是绑定事件的意思
//[]表示绑定属性
//[()]表示双向绑定
this.communityEvent.emit('call parent');
}
}
app.component.ts
import { Component} from '@angular/core';
import { ItemComponent } from './item/item.component';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
callParent(val) {
console.log('child is call me!');
console.log(val);
}
}
组件嵌套
ps:以前学reactjs时看了许多,许多人写文档都是说,组件复用,但是却没写嵌套,没嵌套复用个毛线啊。所以这个相当重要
app.component.html
<div class="demo5">
<p>嵌套</p>
<div>
<app-content>
<app-item #target></app-item>
</app-content>
</div>
<p>获取多个分别嵌套进去</p>
<div>
<app-content-parts>
<div class="parta"><span>this is part1</span></div>
<div class="partb">this is part2</div>
<div class="not-content">can't content</div>
</app-content-parts>
</div>
</div>
content.component.html
<div>
<p>ng-content show</p>
<ng-content></ng-content>
</div>
content-parts.component.html
<div>
content-parts works!
<ng-content select='.parta'></ng-content>
<div>
<p>this is partb content</p>
<ng-content select='.partb'></ng-content>
</div>
</div>
如果是自己封装通用的组件,且依赖大于一个最好用一个module来引入,并且在module中exports最外层这些component
用到这个组件时直接imports这module,爽歪歪!