Angular 6 開發踩坑

Sleepy ?發表於2019-05-22
  1. ng new project-name --style=scss --routing 初始化工程檔案之後,如果執行 ng serve -o會出現如下錯誤:
ERROR in ./src/styles.scss (./node_modules/@angular-devkit/build-angular/src/angular-cli-files/plugins/raw-css-loader.js!./node_modules/postcss-loader/src??embedded!./node_modules/sass-loader/lib/loader.js??ref--14-3!./src/styles.scss)
Module build failed (from ./node_modules/sass-loader/lib/loader.js):
Error: Cannot find module 'node-sass'
    at Function.Module._resolveFilename (module.js:548:15)
    at Function.Module._load (module.js:475:25)
    at Module.require (module.js:597:17)
    at require (internal/module.js:11:18)
    at Object.sassLoader (/home/local/BROCELIA/zhli/WebstormProjects/ng6-project/node_modules/sass-loader/lib/loader.js:46:72)
ℹ 「wdm」: Failed to compile.
複製程式碼

因為缺少依賴包:node-sass,但是隻用sudo npm install node-sass是行不通的,需要使用:sudo npm install --save-dev --unsafe-perm node-sass才可以正常安裝這個依賴包。

  1. 如果使用sudo初始化工程檔案,資料夾會被鎖定,導致webstorm無法獲取許可權無法編輯文字,所以在terminal中使用sudo chmod 777 ng6-project來給資料夾賦予所有許可權,然後使用sudo chown -R zhli /home/local/BROCELIA/zhli/WebstormProjects 來給父資料夾賦予許可權,此時就可以正常編輯檔案了。
  2. Angular工程中使用Material icons時候,先在src/index.html<head>中新增依賴:
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Montserrat:300,700" rel="stylesheet">
複製程式碼

然後使用引用模板:<i class="material-icons">account_circle</i>即可,如果圖片沒有重新整理,嘗試sudo npm install material-design-icons 然後 ng -serve -o重啟伺服器。

  1. 依賴安裝指令集合:
// 動畫依賴
sudo npm install @angular/animations@latest --save
// Material icons
sudo npm install material-design-icons
複製程式碼
  1. 建立元件指令集合:
// 建立新元件
ng generate component details
// Request API 服務
ng generate service data
複製程式碼
  1. Angular 動畫:

在app.module,ts中引用import {BrowserAnimationsModule} from '@angular/platform-browser/animations';並在import中新增BrowserAnimationsModule。 然後在component中新增依賴import {trigger, style, transition, animate, keyframes, query, stagger} from '@angular/animations';並在@component識別符號中定義動畫。

animations: [
    trigger('listStagger', [
      transition('* <=> *', [
        query(
          ':enter',
          [
            style({ opacity: 0, transform: 'translateY(-15px)' }),
            stagger(
              '50ms',
              animate(
                '550ms ease-out',
                // animate ('duration delay easing')
                style({ opacity: 1, transform: 'translateY(0px)' })
              )
            )
          ],
          { optional: true }
        ),
        query(':leave', animate('50ms', style({ opacity: 0 })), {
          optional: true
        })
      ])
    ])
複製程式碼

其中:

  • Trigger用來觸發動畫
  • transition用來定義狀態的轉換:open => close, close => open, * => open, * => close, close => *, open => *,void => *, ':enter', ':leave'
  • style用來定義樣式,對應不同的state,也定義在不同的state中。樣式的名稱要用駝峰法命名:camelCase
state('open', style({
  height: '200px',
  opacity: 1,
  backgroundColor: 'yellow'
})),
複製程式碼
  • animate就是動畫的定義
transition('open => closed', [
    animate('1s')
  ]),
複製程式碼
  • query()用於在已經定義了動畫的元素內部定義其他的動畫,This function targets specific HTML elements within a parent component and applies animations to each element individually
  • tagger()用於在不同的動畫之間定義timing gap,在不同的animation之間增加動畫延遲
  • 引用時,使用@來引用動畫Trigger的名稱: <div [@triggerName]="expression">...</div>;
  1. Routing: 路由詳細教程
  2. 在向app.module.ts中新增HttpClientModule和DataService依賴時,HttpClientModule新增在import中,DataService新增在providers中:
import { HttpClientModule } from '@angular/common/http';
import { DataService } from './data.service';
@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    /**....**/
    HttpClientModule,
  ],
  providers: [DataService],
  bootstrap: [AppComponent]
})
複製程式碼
  1. Angular支援資料雙向繫結:

    資料繫結
    在雙向繫結中,資料屬性值通過屬性繫結從元件流到輸入框([hero]="selectedHero")。使用者的修改通過事件繫結流回元件,把屬性值設定為最新的值((click)="selectHero(hero)")。

  2. template 內聯模板的書寫:包在 ECMAScript 2015 反引號 (`) 中的一個多行字串。 反引號 (`) — 注意,不是單引號 (') — 允許把一個字串寫在多行上, 使 HTML 模板更容易閱讀。

template: `
    <h1>{{title}}</h1>
    <h2>My favorite hero is: {{myHero}}</h2>
    `
複製程式碼

使用模板可以不用再編寫模板檔案(按照需求):

import { Component } from '@angular/core';
 
@Component({
  selector: 'app-root',
  template: `
    <h1>{{title}}</h1>
    <h2>My favorite hero is: {{myHero}}</h2>
    `
})
export class AppComponent {
  title = 'Tour of Heroes';
  myHero = 'Windstorm';
}
複製程式碼
  1. 資料類的建立:
  • 建立資料類:ng generate class data
  • 構造屬性:
    export class Data {
      constructor(
        public id: number,
        public name: string) { }
    }
    複製程式碼
  • 在app.component.ts中匯入data資料類之後就可以在屬性中返回型別化的物件陣列了:
        dataa = [
          new Data(1, 'Windstorm'),
          new Data(13, 'Bombasto'),
          new Data(15, 'Magneta'),
          new Data(20, 'Tornado')
        ];
        myData = this.dataa[0];
    複製程式碼
  1. 語句上下文的互相引用:
<button (click)="onSave($event)">Save</button>
<button *ngFor="let hero of heroes" (click)="deleteHero(hero)">{{hero.name}}</button>
<form #heroForm (ngSubmit)="onSubmit(heroForm)"> ... </form>
複製程式碼

模板上下文中的變數名的優先順序高於元件上下文中的變數名,也就是說上面的 deleteHero(hero) 中,hero 是一個模板輸入變數,而不是元件中的 hero 屬性

相關文章