初涉angular的總結(jié)

初涉angular之自定義指令

1.自定義指令
import {Directive, ElementRef, HostListener} from "@angular/core";

@Directive({
 selector: '[nu-input]'
})
export class InputTrimDirective {
 constructor(public elementRef: ElementRef) {
 }
 @HostListener('keyup', ['$event.target'])
 keyupFun(evt) {
   if (evt.value) {
     this.elementRef.nativeElement.value = evt.value.trim();
   }
 }
}

在app.module聲明指令,在app.module的declarations中聲明才能生效

import {BrowserModule} from '@angular/platform-browser';
import {NgModule} from '@angular/core';
import {FormsModule} from '@angular/forms';
import {AppComponent} from './app.component';
import {InputTrimDirective} from "./direcitve/input-trim.directive";

@NgModule({
 declarations: [
   AppComponent,
   InputTrimDirective 
 ],
 imports: [
   BrowserModule,
   FormsModule,
 ],
 bootstrap: [AppComponent]
})
export class AppModule {
}

通過inport從core庫中導(dǎo)入Directive,HostListener,ElementRef,Input .....的引入。

Directive

用于@Directive裝飾器功能,用于定義這個class是一個指令,通過@Directive修飾這樣就擁有了指令的功能,我們在元組中聲明selector屬性值為[input-trim],方括號的寫法表示是一個屬性指令 還有以下幾種寫法:

element-name: 使用元素名稱選擇
.class: 使用類名選擇
[attribute]: 使用屬性選擇
[attribute=value]:使用屬性和值選擇
:not(sub_selector):只有當(dāng)元素與sub_selector不匹配時才選擇
selector1,selector2:選擇擇selector1或selector2 這里我們采用屬性的方式指定選擇器。
這里采用的是屬性的方式指定選擇器,
@Directive({
selector: '[nu-input]'
})

模板中使用,直接寫 nu-input

HostListener

HostListener 是屬性裝飾器,用來為宿主元素添加事件監(jiān),類似于我們原生JavaScript的addEventListener。 這里我們監(jiān)聽了keyup事件(還可以定義原生JavaScript中的其他事件),當(dāng)表單中有輸入的時候我們就會調(diào)用方法,傳遞了一個$event對象進去,后面緊跟我們觸法keyup事件的方法體
ElementRef(注意:需要在構(gòu)造函數(shù)中注入進去)

用于獲取獲取DOM節(jié)點相關(guān)的屬性
這里我們當(dāng)我們在頁面表單輸入的時候,會調(diào)用keyupFun方法,首先判斷是否有值輸入,有的情況下,我們通過傳遞進來的evt獲取表單的value值,在調(diào)用trim()方法去除空格,賦值給elementRef.nativeElement.value渲染到頁面

import { Input, ElementRef, OnInit, Directive } from '@angular/core';
@Directive({
  selector: '[nu-input]',
  exportAs: 'nuInput',
  host: {
    '[class.nu-input]': 'true'
  }
})
export class NuInput implements OnInit {
  /**
   * 通過size設(shè)置input大小,默認為small, 支持big
   */
  @Input() size: String = 'small';
  constructor(private _elementRef: ElementRef) {
  }
  ngOnInit() {
    (this._elementRef.nativeElement as HTMLElement).classList.add('nu-input-' + this.size);
  }
}
擴展Host

這里如果我們不采用HostListener屬性裝飾器來監(jiān)聽事件,我們可以在指令的 metadata 信息中,設(shè)定宿主元素的事件監(jiān)聽信息,

// 自定義class類名
 host: {
    '[class.nu-input]': 'true'
  }
// 自定義'role-data'屬性
 host: {
    'role-data': 'hello world'
 }
// 監(jiān)聽事件
 host: {
    '(keyup)': 'keyupFun($event.target)'
 }
exportAs

官方解釋是說,exportAs: string:定義一個名字,用于在模板中把該指令賦值給一個變量。給的例子如下

@Directive({
     selector:  'child-dir',
     exportAs:  'child'  
})
 class  ChildDir  { }
 @Component({
  selector:  'main',
  template:  `<child-dir #c="child"></child-dir>`
  })
 class  MainComponent  {
 }
別人的解釋
// 這是NuToolTipDirective元件中的部分內(nèi)容
@Directive({
    selector: '[nu-tooltip]',
    exportAs: 'nuTooltip',
    host: {
        '[class.nu-tooltip-open]': 'isOpen'
    }
})
export class NuToolTipDirective implements AfterViewInit, OnChanges, OnInit, OnDestroy {
     * @ignore 是否顯示tooltip
     */
    isOpen = false;
......
// 在模板中使用
// #tooltip1="nuTooltip"中,nuTooltip就是NuToolTipDirective的exportAs所定義的name,
// 代表了NuToolTip這個指令本身,button中定義#tooltip1指代nuTooltip
// isOpen是元件指令中定義的Boolen值,在模板中tooltip1.isOpen調(diào)用
<button nu-button nu-tooltip #tooltip1="nuTooltip"></button><span>{{tooltip1.isOpen}}</span>
//未指代,不能獲取isOpen
<button nu-button nu-tooltip #tooltip2></button><span>{{tooltip2.isOpen}}</span>

初涉angular之組件通訊

1.子component調(diào)用父component的方法或?qū)傩灾?/h5>
@Input
效果圖

通過按鈕獲得hobby name,顯示在list下方。
1.home.component.html

<div class="home-list">
  <table>
    <tr>
      <td>編號</td>
      <td>愛好</td>
      <td>幸福指數(shù)</td>
      <td>操作</td>
    </tr>
    <tr *ngFor="let item of hobby; let i = index;">
      <td>{{i}}</td>
      <td>{{item.name}}</td>
      <td>{{item.fzs}}</td>
      <!--getDate()獲取hobby name-->
      <td><button (click)="getDate(item.name)">選擇</button></td>
    </tr>
  </table>
  <p>我選擇的是:</p>
  <!--調(diào)用子組件-->
  <app-hobby [hobbyGetName]="hobbyName"></app-hobby>
</div>

2.home.component.ts

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
  public hobbyName: string; //傳給子組件的值
  public hobby = [
    {name: 'code', fzs: '100'},
    {name: 'sing', fzs: '200'},
    {name: 'play', fzs: '1000'},
    {name: 'sleep', fzs: '500'}
    ];
  constructor() { }

  ngOnInit() {
  }
  getDate(name) {
    console.log(name);
    //將獲取的值給hobbyName 賦值
    this.hobbyName = name; 
  }
}

3.子組件

import {Component, Input, OnInit} from '@angular/core';

@Component({
  selector: 'app-hobby',
  templateUrl: './hobby.component.html',
  styleUrls: ['./hobby.component.css']
})
export class HobbyComponent implements OnInit {
//@Input接受父組件傳過來的[值]
  @Input() hobbyGetName: string;
  constructor() { }

  ngOnInit() {
  }

}

4.顯示在view中

<p>{{hobbyGetName}}</p>
2.父component調(diào)用子component的方法或?qū)傩灾?/h5>
@Output 父組件接收子組件的數(shù)據(jù)時,子組件暴露一個EventEmitter屬性,當(dāng)事件發(fā)生時,子組件利用該屬性emits(向上彈射)事件。父組件綁定到這個事件屬性,并在事件發(fā)生時作出回應(yīng)。
效果圖

hobby.component.html

<p>{{hobbyGetName}}</p>
<button (click)="Descrip()">description</button>

hobby.component.ts

import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';

@Component({
  selector: 'app-hobby',
  templateUrl: './hobby.component.html',
  styleUrls: ['./hobby.component.css']
})
export class HobbyComponent implements OnInit {
  @Input() hobbyGetName: string;
  @Output() Detail: EventEmitter<any> = new EventEmitter();
  public hobbyDetail = [
    {name: 'code', description: '小辮子飛起!'},
    {name: 'sing', description: '聽歌要命!'},
    {name: 'play', description: '莫不是怕上天?'},
    {name: 'sleep', description: '君何不扶搖之上?'}
  ];
  constructor() { }

  ngOnInit() {
  }
  Descrip() {
    console.log(this.hobbyGetName);
    this.hobbyDetail.forEach((i) => {
      if (this.hobbyGetName === i.name) {
        this.Detail.emit(i.description);
      }
    });
  }
}

home.component.html

  <p>我選擇的是:</p>
  <app-hobby [hobbyGetName]="hobbyName" (Detail)="hobbyDse($event)"></app-hobby>
  <p>hobby的描述: </p>
  <span>{{hobbyDescription}}</span>
</div>

home.component.ts

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
  public hobbyDescription: string;
  constructor() { }

  ngOnInit() {
  }
  hobbyDse(e) {
    console.log(e);
    this.hobbyDescription = e;
  }
}

3.無關(guān)聯(lián)component之間的通訊

Service服務(wù)

創(chuàng)建一個service.ts

//命令
ng generate service  'service name'
ng generate service  home
創(chuàng)建成功

在組件通用資源中,分享的是靜態(tài)資源。例如login component與nav-title component的title是一樣的,共享login的title。so ,在login.service.ts中,

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class LoginService {
  /*共享資源為靜態(tài)值*/
  //分享title值
  title = 'angular';
  constructor() { }
}

在nav-title.component.ts中,訂閱服務(wù)

import {Component, OnInit} from '@angular/core';
//加入共享的 LoginService
import { LoginService } from '../../login/login.service';

@Component({
  selector: 'app-nav-title',
  templateUrl: './nav-title.component.html',
  styleUrls: ['./nav-title.component.css']
})
export class NavTitleComponent implements OnInit {
  public title: string;
  constructor(public service: LoginService ) {//訂閱service
    console.log(this.service.title);
    this.title = this.service.title;//賦值給nav-title的title
  }
  ngOnInit() {
  }
}

初涉angular之路由

回憶一下Vue的路由

//在template模塊中直接路由,類似a標簽
 <router-link :to="/prodution">......</router-link>
//在方法中條用路由
this.$router.push({path: '/login'});

在router的index.js中,

//引入依賴模塊
import Vue from 'vue'
import Router from 'vue-router'
//引入頁面
import login from '@/page/login/login'
Vue.use(Router)

const  router = new Router({
  routes: [
    {
      path: '/',
      name: 'Index',
      component: Index
    },{
      path:'/login',
      name:'login',
      component:login
    }
  ]
})

在angular中,路由與Vue相似,但是存在很大的不同
1.在cli創(chuàng)建時,會提示是否需要路由。


創(chuàng)建命令

輸入y,之后會在app.modules.ts引入import { AppRoutingModule } from './app-routing.module'
2.在app-routing.module.ts中,

//模塊依賴引入
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
//components
import {LoginComponent} from './login/login/login.component';
import {HomeComponent} from './home/home/home.component';

//routes
const routes: Routes = [
//定義路由跳轉(zhuǎn)
  {path: '', component: LoginComponent},
  {path: 'home', component: HomeComponent}
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

3.在component中,

 <a href="#" routerLink="/user">User</a>

4.在方法中,

import {Component, OnInit, NgZone} from '@angular/core';//路由依賴
import { Router } from '@angular/router';//路由依賴
import { LoginService } from '../login.service';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
  public username: string;
  public password: string;

  constructor(
    public service: LoginService,
    public ngZone: NgZone,//訂閱
    public router: Router,//訂閱
  ) {
     console.log(this.service.title);
  }

  ngOnInit() {
  }
  loginIn() {
    if (this.username == '123' && this.password == '123') {
      //成功后,跳轉(zhuǎn)home主頁
      this.ngZone.run(() => this.router.navigate(['home'])).then();
    }
  }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容