发表于: 2017-06-21 22:31:02
2 931
今天完成的事情:
稍微深入学习Angular依赖注入,恩。
明天计划的事情:
依赖注入还有两节比较难的东西,明天看完。
遇到问题:
其实依赖注入是个很深的东西,了解的越多就越感觉什么都不会。一山更比一山高。
收获:
昨天写了自定义属性指令,今天写结构指令吧。
Angular 自定义结构指令
1. <ng-template>
元素
import { Component, TemplateRef, ViewContainerRef, ViewChild,AfterViewInit } from '@angular/core';@Component({selector: 'app-code404',template: `<!-- 这里使用一个模板变量,在组件中使用@ViewChild装饰器获取模板元素--><ng-template #tpl>Big Keriy !</ng-template>`,})export class Code404Component implements AfterViewInit{// @ViewChild 装饰器获取模板元素@ViewChild('tpl')tplRef: TemplateRef<any>;constructor(private vcRef: ViewContainerRef) {}ngAfterViewInit() {// 使用ViewContainerRef对象的createEmbeddedView方法创建内嵌视图。this.vcRef.createEmbeddedView(this.tplRef);} }
这样其实我们在视图中就得到了一个什么...啊,就是一个'Big Keriy !'的字符串。
2. ngTemplateOutlet
指令
ngTemplateOutlet
和routerOutlet
是一个意思,将视图(ngTemplateoutlet
下面。
import { Component } from '@angular/core';@Component({selector: 'app-code404',template: `<ng-template #stpl>Hello, Semlinker!</ng-template><ng-template #atpl>Big Keriy !</ng-template><div [ngTemplateOutlet]="atpl"></div><div [ngTemplateOutlet]="stpl"></div>`, })export class Code404Component { }
最终的视图应该是:
Big Keriy !Hello, Semlinker!
ngOutletContex
看名字就知道意思。ngTemplateOutlet
指令基于TemplateRef
对象,在使用ngTemplateOutlet
指令时,可以通过ngTemplateOutletContext
属性来设置来设置EmbeddedViewRef
的上下文对象。可以使用let
语法来声明绑定上下文对象属性名。
import { Component, TemplateRef, ViewContainerRef, ViewChild,AfterViewInit } from '@angular/core';@Component({selector: 'app-code404',template: `<!-- 这里的messagey映射到下面context中message 再使用插值表达式的方式显示message的值 --><ng-template #stpl let-message="message"><p>{{message}}</p></ng-template><!-- 这里的messagey映射到下面context中message , let-msg是一种与语法糖的方式变量名是msg--><ng-template #atpl let-msg="message"><p>{{msg}}</p></ng-template><!-- 若不指定变量值那么将显示 $implicit 的值--><ng-template #otpl let-msg><p>{{msg}}</p></ng-template><div [ngTemplateOutlet]="atpl"// 这里ngOutletContext绑定的是context对象[ngOutletContext]="context"></div><div [ngTemplateOutlet]="stpl"[ngOutletContext]="context"></div><div [ngTemplateOutlet]="otpl"[ngOutletContext]="context"></div>`,})export class Code404Component implements AfterViewInit{@ViewChild('tpl')tplRef: TemplateRef<any>;constructor(private vcRef: ViewContainerRef) {}ngAfterViewInit() {this.vcRef.createEmbeddedView(this.tplRef);}context = { message: 'Hello ngOutletContext!',$implicit: 'great, Semlinker!' };// 这里的$implicit是固定写法}
先看输出的视图:
Hello ngOutletContext!Hello ngOutletContext!Hello, Semlinker!
3. ngComponentOutlet
指令
听着名字就很爽,这不是插入视图的,是插入组件的!
该指令使用声明的方式,动态加载组件。
先写组件,里面有两个。。组件:
@Component({selector: 'alert-success',template: `<p>Alert success</p>`,})export class AlertSuccessComponent { }@Component({selector: 'alert-danger',template: `<p>Alert danger</p>`,})export class AlertDangerComponent { }@Component({selector: 'my-app',template: `<h1>Angular version 4</h1><ng-container *ngComponentOutlet="alert"></ng-container><button (click)="changeComponent()">Change component</button>`, })export class AppComponent {alert = AlertSuccessComponent;changeComponent() {this.alert = AlertDangerComponent;}}
当然,还需要在模块中声明入口:
// app.module.ts@NgModule({// ...declarations: [AppComponent,SignUpComponent,AlertSuccessComponent,AlertDangerComponent],entryComponents: [AlertSuccessComponent,AlertDangerComponent],// ...})
这样就可以使用ngComponentOutlet
指令来插入组件玩耍了:
<!-- 简单语法 --><ng-container *ngComponentOutlet="componentTypeExpression"></ng-container><!-- 完整语法 --><ng-container *ngComponentOutlet="componentTypeExpression;injector: injectorExpression;content: contentNodesExpression;"></ng-container>
这是一个完整语法简单的例子:
// ...@Component({selector: 'ng-component-outlet-complete-example',template: `<ng-container *ngComponentOutlet="CompleteComponent;injector: myInjector;content: myContent"></ng-container>`})class NgTemplateOutletCompleteExample {// This field is necessary to expose CompleteComponent to the template.CompleteComponent = CompleteComponent;myInjector: Injector;myContent = [[document.createTextNode('Ahoj')], [document.createTextNode('Svet')]];constructor(injector: Injector) {this.myInjector = ReflectiveInjector.resolveAndCreate([Greeter], injector);}}
4. 创建结构指令
也想不出来一个什么好例子,抄一个例子过来:
// uless.directive.tsimport { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';@Directive({selector: '[exeUnless]'})export class UnlessDirective {@Input('exeUnless')set condition(newCondition: boolean) { // set conditionif (!newCondition) {this.viewContainer.createEmbeddedView(this.templateRef);} else {this.viewContainer.clear();}}constructor(private templateRef: TemplateRef<any>,private viewContainer: ViewContainerRef) {}}import { Component } from '@angular/core';@Component({selector: 'app-root',template: `<h2 *exeUnless="condition">Hello, Semlinker!</h2>`,})export class AppComponent {condition: boolean = false;}// app.component.tsimport { Component } from '@angular/core';@Component({selector: 'app-root',template: `<h2 *exeUnless="condition">Hello, Semlinker!</h2>`,})export class AppComponent {condition: boolean = false;}
评论