<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                # Binding to user input events 在新增及編輯功能中,我們在`form 表單`中使用了`(ngSubmit)="onSubmit()"`來觸發了C層的`onSubmit()`方法最終完成表單的提交。`(ngSubmit)="onSubmit()"`:當用戶點擊表單提交時,觸發我們C層的`onSubmit()`方法。這個過程便是:` Binding to user input events 綁定到用戶輸入事件`。 用戶在使用系統過程中與網頁的互動,我們稱為`event 事件`。`html event`分別五大類:`windows 事件`,比如我們對瀏覽器的窗口改變大小時會觸發該事件;`Form 事件`,比如我們修改某個表單的值;`Keyboard 事件`,比如我們按下了某個按鍵;`Mouse 事件`,當我們點擊鼠標時會觸發;`Media 事件`,控制一些媒體的播放,比如`mp3`的播放、暫停。在`angular`中我們可以非常簡單的使用內置的一些事件,比如使用`(ngSubmit)`來獲取表單事件,使用`(click)`來獲取點擊事件。 ## click 在教師列表中,為每一項添加一個刪除按鈕,當此按鈕被點擊時,觸發C層的`onDelete`方法。 app.component.html ``` <td><a [routerLink]="['/edit', teacher.id]">編輯</a> &nbsp;&nbsp;<button (click)="onDelete()" ?>刪除</button></td> ``` * ? 添加按鈕,并綁定`click`事件 app.component.ts ``` onDelete(): void { console.log('click delete'); } ``` > 我們約定,與前臺事件進行綁定的方法以`on`打頭。比如`onSubmit`、`onDelete`。 ## 測試 ![](https://img.kancloud.cn/17/ab/17abb33af91bb913044d4a8f800fdf4a_701x169.png) 打開[http://localhost:4200/](http://localhost:4200/)及瀏覽器控制臺,點擊`刪除`按鈕后在控制臺中查看信息,符合預期。 # 傳入待刪除對象 在事件中調用C層的方法時,還可以進行相應的傳值。 ```html <td><a [routerLink]="['/edit', teacher.id]">編輯</a> &nbsp;&nbsp;<button (click)="onDelete(teacher)?">刪除</button></td> ``` * ? 向刪除方法中傳入當前行的對象`teacher` ```js onDelete(teacher: any): void { ? console.log(teacher); ? } ``` * ? 在方法中增加參數`teacher`。 * ? 測試 ## 測試 ![](https://img.kancloud.cn/b1/e9/b1e98763cd1a438a172aeba68cffccd8_936x171.png) # delete方法請求后臺 同`get`方法的相同,我們直接調用`httpClient.delete(url: string)`方法來進行`delete`方法的請求. ```js /** * 點擊刪除按鈕時刪除對應的教師 * @param teacher 要刪除的教師 */ onDelete(teacher: any): void { const url = 'http://localhost:8080/Teacher/' + teacher.id; this.httpClient.delete(url) .subscribe(() => { console.log('刪除成功'); this.ngOnInit(); ? }, () => { console.log('刪除失敗'); }); } ``` * ? 刪除成功后,重新加載數據。 ## 測試 ![](https://img.kancloud.cn/bd/2b/bd2ba4127c9544a3d4b524f1c7f6b683_428x36.png) 在開啟后臺的情況下,將出現`403`無此權限錯誤;在未開啟后臺的情況下,將出現`404`資源不存在錯誤。在未對接后臺前,這都是正常的。 # TypeScript `JavaScript`是個偉大、靈活的語言。同時它有具有著上手極簡單、精通特別難的特點。這有些類似于網絡游戲,剛剛接觸的時候感覺沒有什么進而會給你極其優越的成就感;但隨著時間的推移總會出一現新奇的東西需要學習和掌握。當然了,對于我們而言便是一路踩坑、爬坑的經歷。`TypeScript`及其類似的語言正是看到了這一點,使得新手在使用`JavaScript`能夠少踩一些坑,使得習慣了使用不太靈活的面向對象的語言的開發人員能夠快速開發`JavaScript`程序。其實本質上`TypeScript`并不是一門語言而一個解析器,它使用一些新的語法、規范來約束我們的開發,而最終交給瀏覽器去執行的仍然是 `JavaScript`,只不過這個 `JavaScript`是由`TypeScript`翻譯后自動生成的。 官方如是說:**TypeScript is a superset of JavaScript that compiles to clean JavaScript output.**、**TypeScript is a typed superset of JavaScript that compiles to plain JavaScript. Any browser. Any host. Any OS. Open source.** 如官方所說它是一個`typed superset 有類型的超集`。只所以這樣說,是由于`javascript`其實是`untyped 弱類型`的語言。比如我們可以在`js`中這樣定義`var a = 3; a = 'yunzhi'; `,這不會發生任何問題。但如果在`ts`中這樣寫:`let a = 3; a = 'yunzhi';`便會引發一個編譯錯誤: `Error:(42, 5) TS2322: Type '"yunzhi"' is not assignable to type 'number'.`。這時由于`ts`是一種強類型語言,和其它的強類型語言一樣,在`ts`中變量一旦規定了類型,那么在賦值時就必須與該類型相匹配。但由于`ts`的最終目標是翻譯為`js`,同時呢在`ts`中我們還可以使用原有的一些`js`庫,那么就需要有一個兼容性的問題,所以`ts`中使有了類型`any`。所以在`ts`中這樣編寫是沒有問題的:`let a: any; a = 3; a = 'yunzhi';`。而`any`則代表任意類型。 ## 語法較驗 在實際的開發中,我們應該最大限度的去規避使用`any`類型,這是因為我們無法由`any`類型中得到任何的幫助信息。比如我們剛剛編寫的:`onDelete(teacher: any): void`對于1個月后的自己,此函數等價于`onDelete(a: any): void`,而我們對`a`的值、類型一無所知。 而`typescript`有著強大的語法較驗功能,該功能能夠幫助我們規避一些拼寫時的低端錯誤。比如我們可以在`onDelete`方法中注明該變量的類型或成功調用該方法該變量需要具有的類型。 ``` onDelete(teacher: {id: number} ?):void { const url = 'http://localhost:8080/Teacher/' + teacher.id; this.httpClient.delete(url) .subscribe(() => { console.log('刪除成功'); this.ngOnInit(); }, () => { console.log('刪除失敗'); }); } ``` * ? 接收的參數teacher的類型為`{} 對象`,且該`{} 對象`必須存在`id`屬性,該屬性的類型必須為`number`。 如此一來,如果在進行調用時傳入的對象無`id`屬性,或是`id`屬性的類型不是`number`,`ts`在編譯過程中便會發生錯誤來提醒我們此次的調用存在問題,從而避免了生產環境中的一些不可預測錯誤。同時其它的團隊成員只要看到了該參數的定義便會清晰:該參數接收的對象中必須有`id`屬性,且此屬性的值的類型為`number`,在進行調用時需要遵循此規劃來做。 在后續的教程中,我們將越來越多的`定義參數類型`的方法來避免語法錯誤。除此以外,這種寫法還有一個好處是我們以后由于一些特定的不可控的事情導致需要重寫該功能時,我們可以根據參數以及注釋信息達到快速二次開發的目的。我們認為:軟件在開發中需求必然會經過變更,而我們做的所有的規范都是為了滿足需求的變更。我們希望隨著項目的逐漸增大,盡量少的增加維護難度,最終達到易維護的系統。爭取能夠使得一個團隊寫的代碼就像一個人寫的一樣,爭取今天讀一個月以前寫的代碼就像讀昨天寫的代碼一樣。把開發軟件做成一個實實在在的工程,這可能就是`軟件工程`名稱的由來吧。 # 前后臺對接總結 `delete`請求我們接觸的第4個請求方法,除此以外我們還會接觸到`options`及`patch`方法,我們來簡單總結一下: | 請求方法 | 前臺方法 | 后臺方法 | 適用場景 | | --- | --- | --- | --- | | get | httpClient.get(url: string) | @GetMapping | 按條件查詢獲取后臺的所有數據 | | get | httpClient.get(url: string) | @GetMapping("{id}") | 按條件查詢獲取后臺的某條數據 | | post | httpClient.post(url: string, data: Object) | @PostMapping, @RequestBody | 新增數據 | | put | httpClient.put(url: string, data: Object) | @PutMapping("{id}") @RequestBody | 更新某條數據(一般用于更新實體的所有字段) | | delete | httpClient.delete(url: string) | @DeleteMapping("id") | 刪除某條數據 | | options | - | 瀏覽器自動發生,用于確認某些資源的訪問權限 | | patch | httpClient.patch(url: string, data: Object) | @PatchMapping("{id}") @RequestBody | 更新某條數據(一般用于更新實體的部分字段) | # 參考文檔 | 名稱 | 鏈接 | 預計學習時長(分) | | --- | --- | --- | | TypeScript(github) | [https://github.com/microsoft/TypeScript](https://github.com/microsoft/TypeScript) | 1 | | TypeScript | [https://www.typescriptlang.org/](https://www.typescriptlang.org/) | 1 | | TypeScript 基礎類型 | [https://www.runoob.com/typescript/ts-type.html](https://www.runoob.com/typescript/ts-type.html) | 15 | | TypeScript 函數 | [https://www.runoob.com/typescript/ts-function.html](https://www.runoob.com/typescript/ts-function.html) | 15 | | 用戶輸入 | [https://www.angular.cn/guide/user-input](https://www.angular.cn/guide/user-input) | 10 | | 源碼地址 | [https://github.com/mengyunzhi/spring-boot-and-angular-guild/releases/tag/step2.5.1](https://github.com/mengyunzhi/spring-boot-and-angular-guild/releases/tag/step2.5.1) | - |
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看