@Attribute
获取宿主元素的对应的属性值。
@Directive({
selector: '[test]'
})
export class TestDirective {
constructor(@Attribute('type') type ) {
console.log(type); // text
}
}
@Component({
selector: 'my-app',
template: `
<input type="text" test>
`,
})
export class App {}
@component
声明组件。
@Component({
selector: 'greet',
template: 'Hello {{name}}!'
})
class Greet {
name: string = 'World';
}
@ContentChild
和@ContentChildren类似,只返回第一个符合的view DOM
@Component({
selector: 'tabs',
template: `
<ng-content></ng-content>
`,
})
export class TabsComponent {
@ContentChild("divElement") div: any;
ngAfterContentInit() {
console.log(this.div);
}
}
@Component({
selector: 'my-app',
template: `
<tabs>
<div #divElement>Tada!</div>
</tabs>
`,
})
export class App {}
@ContentChildren
和@ContentChild类似,获取ng-content中符合的view DOM,只有ngAfterContentInit后才会有view DOM,QueryList才会初始化
@Component({
selector: 'tab',
template: `
<p>{{title}}</p>
`,
})
export class TabComponent {
@Input() title;
}
@Component({
selector: 'tabs',
template: `
<ng-content></ng-content>
`,
})
export class TabsComponent {
@ContentChildren(TabComponent) tabs: QueryList<TabComponent>
ngAfterContentInit() {
this.tabs.forEach(tabInstance => console.log(tabInstance))
}
}
@Component({
selector: 'my-app',
template: `
<tabs>
<tab title="One"></tab>
<tab title="Two"></tab>
</tabs>
`,
})
export class App {}
@directive
声明指令。
@Directive({
selector: '[my-button]',
host: {
'[class.valid]': 'valid', // 动态属性绑定
'role': 'button', // 静态属性绑定
'(click)': 'onClick($event.target)' // 事件监听
}
})
class NgModelStatus {
constructor(public control:NgModel) {}
get valid { return this.control.valid; }
get invalid { return this.control.invalid; }
}
@host
从当前先上获取符合的父view DOM,知道最顶层的宿主元素。
@Component({
selector: 'cmp',
template: `
cmp
`,
})
export class DIComponent {}
@Directive({
selector: "[host-di]"
})
export class HostDI {
constructor(@Host() cmp: DIComponent) {
console.log(cmp);
}
}
@Component({
selector: 'my-app',
template: `
<cmp host-di></cmp>
`,
})
export class App {}
@HostBinding
设置宿主元素的属性绑定。
@Directive({
selector: '[host-binding]'
})
export class HostBindingDirective {
@HostBinding("class.tooltip1") tooltip = true; // 设置 "tooltip1" 样式类
@HostBinding("class.tooltip2") // 设置 "tooltip2" 样式类
get tooltipAsGetter() {
// your logic
return true;
};
@HostBinding() type = "text"; // 直接设置 type="text"
}
@Component({
selector: 'my-app',
template: `
<input type="text" host-binding> // 在这个宿主元素上增加 "tooltip" 样式类
`,
})
export class App {}
@HostListener
宿主元素的事件监听。
@Directive({
selector: '[count]'
})
export class HostListenerDirective {
numClicks = 0;
numClicksWindow = 0;
@HostListener("click", ["$event"]) // 当前宿主元素,即input
onClick(event) {
console.log(this.numClicks++);
}
@HostListener("window:click", ["$event"]) //还可以支持 window,document,body 上的事件
onClick(event) {
console.log("Num clicks on the window:", this.numClicksWindow++);
}
}
@Component({
selector: 'my-app',
template: `
<input type="button" count value="+">
`,
})
export class App {}
@Inject
指明依赖。
@Component({
selector: 'cmp',
template: `
cmp
`
})
export class DIComponent {
constructor(@Inject(Dependency) public dependency) {}
}
@Injectable
声明类可以被DI使用。
@Injectable()
export class WidgetService {
constructor(
public authService: AuthService) { }
}
@input
定义组件的属性。
@Component({
selector: 'my-button',
template: `
<button (click)="click($event)">{{name}}</button>
`
})
export class DI2Component {
@Input() name ;
@Output() myClick: EventEmitter<any> = new EventEmitter();
click() {
this.myClick.emit('click');
}
}
@NgModule
定义module。
@NgModule({
imports: [ CommonModule ],
declarations: [
DIComponent,
HostBindingDirective,
HostDI
],
providers: [{ provide: Dependency, useClass: ParentDependency}],
exports: [
DIComponent,
HostBindingDirective,
HostDI
]
})
export class DemoModule {}
@optional
依赖可选
class OptionalDependency {}
@Component({
selector: 'cmp',
template: `
cmp
`,
})
export class DIComponent {
constructor(@Optional() public dependency: OptionalDependency) {}
}
@output
定义组件的事件。
@Component({
selector: 'my-button',
template: `
<button (click)="click($event)">{{name}}</button>
`
})
export class DI2Component {
@Input() name ;
@Output() myClick: EventEmitter<any> = new EventEmitter();
click() {
this.myClick.emit('click');
}
}
@pipe
定义管道。
@Pipe({
name: 'isNull'
})
export class IsNullPipe implements PipeTransform {
transform (value: any): boolean {
return isNull(value);
}
}
@self
只使用自身的providers的定义,不通过inject tree查找依赖。
class Dependency {}
class ChildDependency {
constructor() {
console.log("ChildDependency");
}
}
class ParentDependency {
constructor() {
console.log("ParentDependency");
}
}
@Component({
selector: 'cmp',
template: `
cmp
`,
providers: [{ provide: Dependency, useClass: ChildDependency }]
})
export class DIComponent {
constructor(@Self() public dependency: Dependency) {} // 注入的为 ChildDependency
}
@Component({
selector: 'my-app',
template: `
<cmp></cmp>
`,
})
export class App {}
@NgModule({
imports: [ BrowserModule ],
declarations: [ App, DIComponent],
providers: [{ provide: Dependency, useClass: ParentDependency }],
bootstrap: [ App ]
})
export class AppModule {}
@SkipSelf
自身组件中定义的providers无效,从parent injector中查找依赖。
class Dependency {}
class ChildDependency {
constructor() {
console.log("ChildDependency");
}
}
class ParentDependency {
constructor() {
console.log("ParentDependency");
}
}
@Component({
selector: 'cmp',
template: `
cmp
`,
providers: [{ provide: Dependency, useClass: ChildDependency }]
})
export class DIComponent {
constructor(@SkipSelf() public dependency: Dependency) {}
}
@Component({
selector: 'my-app',
template: `
<cmp></cmp>
`,
})
export class App {}
@NgModule({
imports: [ BrowserModule ],
declarations: [ App, DIComponent],
providers: [{ provide: Dependency, useClass: ParentDependency }],
bootstrap: [ App ]
})
export class AppModule {}
@ViewChild
和@ViewChildren类似,不同点是只获取第一个符合的view DOM,不能获取ng-content中的内容。
@Component({
selector: 'alert',
template: `
{{type}}
`,
})
export class AlertComponent {
@Input() type: string = "success";
}
@Component({
selector: 'my-app',
template: `
<alert></alert>
<div #divElement>Tada!</div>
`,
})
export class App {
// This will return the native element
@ViewChild("divElement") div: any;
// This will return the component instance
@ViewChild(AlertComponent) alert: AlertComponent;
ngAfterViewInit() {
console.log(this.div);
console.log(this.alert);
}
}
@ViewChildren
和@ViewChild类似,获取view DOM集合,ngAfterViewInit后QueryList才会初始化。
@Component({
selector: 'alert',
template: `
{{type}}
`,
})
export class AlertComponent {
@Input() type: string = "success";
}
@Component({
selector: 'my-app',
template: `
<alert></alert>
<alert type="danger"></alert>
<alert type="info"></alert>
`,
})
export class App {
// 获取组件实例
@ViewChildren(AlertComponent) alerts: QueryList<AlertComponent>
// 获取DOM element
@ViewChildren(AlertComponent, { read: ElementRef }) alerts2: QueryList<AlertComponent>
// 需要动态创建组件或者模板时,需要获取 ViewContainerRef
@ViewChildren(AlertComponent, { read: ViewContainerRef }) alerts3: QueryList<AlertComponent>
ngAfterViewInit() {
this.alerts.forEach(alertInstance => console.log(alertInstance));
this.alerts2.forEach(alertInstance => console.log(alertInstance));
}
}