<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>

                有了前面`Hello World`的經驗,我們如下完成前后臺的對接工作。 # 引用HttpClientModule模塊 app.module.ts ```js import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import {HttpClientModule} from '@angular/common/http'; // ? @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, AppRoutingModule, HttpClientModule // ? ], providers: [], bootstrap: [AppComponent] }) export class AppModule { } ``` * 說明要引用的模塊所在的具體位置,并引入到當前文件中。 * 將要引用的模塊引入到angular中。 # 注入HttpClient對象 app.component.ts ```js import {Component} from '@angular/core'; import {HttpClient} from '@angular/common/http'; // ? @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.sass'] }) export class AppComponent { title = 'web-app'; // 定義教師數組 teachers = new Array( { id: 1, name: '張三', username: 'zhangsan', email: 'zhangsan@yunzhiclub.com', sex: '男', }, { id: 2, name: '李四', username: 'lisi', email: 'lisi@yunzhiclub.com', sex: '女', } ); constructor(private httpClient: HttpClient) { // ? } } ``` * ? 說明要引用的模塊所在的具體位置,并引入到當前文件中。 * ? 將HttpClient對象注入到當前的組件中。 # 發起請求 在前面的小節中,我們直接在構造函數中進行數據的請求。雖然在當前的系統中,這樣做并沒有發現在有任何的問題,但這種做法是官方強烈禁止的,官方的建議是:只在構造函數中完成依賴注入,其它的初始化的操作應該放到`ngOnInit`中進行。按此思想,我們對原組件進行改造。 ```js import {Component, OnInit} from '@angular/core'; import {HttpClient} from '@angular/common/http'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.sass'] }) /** * 實現OnInit接口,該接口規定了ngOnInit方法。 * angular在組件準備完畢后,將自動調用ngOnInit方法 */ export class AppComponent implements OnInit { // 定義教師數組 teachers = new Array(); constructor(private httpClient: HttpClient) { } /** * 該方法將在組件準備完畢后被調用 */ ngOnInit() { /* 后臺數據的請求地址,如果變量定義后不再重新賦值,則應該使用const來定義 */ const url = 'http://localhost:8080/Teacher/'; /* 定義success方法,用于數據請求成功后回調 */ const success = function(response) { console.log(response); /*注意:這樣寫是不正確的,因為this的作用域是本function,而不是本class*/ this.teachers = response; }; /* 定義error方法,用于數據請求失敗時被調用 */ const error = function(response) { console.log(response); console.error('請求出錯'); }; /* 使用get方法請求url,請求一旦成功后,將調用傳入success方法;如果請求失敗,將調用error方法 */ this.httpClient.get(url) .subscribe(success, error); } } ``` # 測試 我們此時啟動前后臺,然后打開瀏覽器的控制臺,并查看控制臺中發生了什么。 ![](https://img.kancloud.cn/5b/bb/5bbbcef13d6433de32a313eb0f45eb95_1152x167.png) 如果你前面的章節學習的夠踏實,那么在測試以前相信已已經斷言此處將發生一個CORS的錯誤。由于當前我們當前訪問的前臺的地址是`[http://localhost:4200/](http://localhost:4200/)`而發起的請求的地址為`http://localhost:8080/Teacher/`。這兩個地址并沒有在一個域上,所以引起了瀏覽器的CORS保護。瀏覽器這么做并沒有錯,這完全是在保護使用者。 > 域的三要素:協議、地址、端口號。 ## 增加跨域設置 我們來到后臺在getAll方法上增加如下代碼: ```java @CrossOrigin("*") ``` 重新啟動后臺,并刷新網頁,相同的問題又發生了: ![](https://img.kancloud.cn/7e/6b/7e6bb0e975bbec360e0dc2ebb9a33e10_1016x385.png) 控制臺成功的打印了請求返回的數據,但由于`this`作用域的不同,并沒有按我們的想法成功的傳入至`teachers`。 > 同樣的錯誤,我們力爭不出現兩遍,這就要求我們當發生錯誤并成功解決后,把發生問題的情景描述清楚、把解決問題的思路理清楚,然后把它們持久化到我們自己的BLOG中。 ## 解決this作用域 ```js const self = this; ? /* 后臺數據的請求地址,如果變量定義后不再重新賦值,則應該使用const來定義 */ const url = 'http://localhost:8080/Teacher/'; /* 定義success方法,用于數據請求成功后回調 */ const success = function(response) { console.log(response); self.teachers = response; ? }; ``` * ?在此,將this賦值給self(有人也習慣用const what = this;意思是一樣的那)。 * ?此時調用的self即相當于組件中的this。 ## 箭頭函數 除了上面的方法以外,我們還可以使用`ES6`標準下的箭頭函數來解決這個問題。 改寫前: ```js /* 定義success方法,用于數據請求成功后回調 */ const success = function(response) { console.log(response); /*注意:這樣寫是不正確的,因為this的作用域是本function,而不是本class*/ self.teachers = response; }; ``` 改寫后: ```js /* 定義success方法,用于數據請求成功后回調 */ const success = (response) => { ? console.log(response); this.teachers = response; ? }; ``` * ? 由 `function (response)`改寫為`(response) =>` * ? 此時在這的`this`便是指此組件了。 ## 測試 此時瀏覽器已為我們自動刷新了頁面,查看最終的效果如下: ![](https://img.kancloud.cn/a0/ea/a0ea034c45d2fe3a9b9dd8e3f7186a2a_397x405.png) # 本節小測 * ?將error改成箭頭函數 * ?將success, error變成匿名箭頭函數,直接在調用`subscribe`時傳入。 ## 上節答案 猜有時候是可以解決我們大部分問題的,每個階段都需要猜的輔助。所以無論你上節的答案是什么,只要能解決你對上節問題的疑惑,那么就是正確可取的。如果我們不小心猜對了,應該驚嘆于自己強大的預測能力;如果不小心猜錯了,那么當有一天我們自己發現這個錯誤或是被其它人指出的時候,就變成了我們知識升華的時候。 我的猜測步驟駋下: 首先,在數據庫中增加測試代碼;其次,在java中增加測試代碼;最后,打斷點進行測試。 ![](https://img.kancloud.cn/26/59/26594262d453849cae6df8bffce32b81_832x378.png) ```java @GetMapping("test") public void test() { /* 定義實現了RowCallbackHandler接口的對象*/ RowCallbackHandler rowCallbackHandler = new RowCallbackHandler() { @Override public void processRow(ResultSet resultSet) throws SQLException { logger.info(resultSet.getString("name_ascii")); logger.info(resultSet.getString("name_gb2312")); logger.info(resultSet.getString("name_utf8")); logger.info(resultSet.getString("name_utf8mb4")); } }; /*定義查詢字符串*/ String queryString = "select * from test"; jdbcTemplate.query(queryString, rowCallbackHandler); } ``` 測試: 全部可用ascii編碼表示時 `a a a a` ![](https://img.kancloud.cn/1e/35/1e354f84f39f1b132d5500a5d55be357_491x169.png) 不可用acsii編碼表示,但可用gb2312表示時 `a 夢 夢 夢` ![](https://img.kancloud.cn/71/6d/716d545625fccbbb75d28ca73fabdaa8_475x167.png) 不可用acsii編碼,不可用gb2312,但可用utf8表示時。`a 夢 ? ?` ![](https://img.kancloud.cn/1f/eb/1febe0ac7ef115e99ba62e9950724cdc_455x168.png) 僅可用utf8mb4表示時 `a 夢 ? ??` ![](https://img.kancloud.cn/b0/ff/b0ff1d903d00be4b201048238c726643_465x175.png) 字符混合時 ![](https://img.kancloud.cn/60/f5/60f502ea9e6a41e58d037d81f48c8a98_464x540.png) 那么,我猜測spring配合mysql完成了以下規則: ① 無論字段指定了什么編碼規則,能用ascii表示就用ascii表示。 ② gb2312編碼下存儲非ascii可表示字符必占用2個字節。 ③ utf8編碼下存儲非ascii可表示字符必占用3個字節。 ④ utf8mb4編碼下存儲非ascii可表示字符時: ? 適用于utf8編碼的,直接使用utf8編碼,占用3個字節。 ? 不適用utf8編碼的,使用utf8mb4編碼,占用4個字節。 ⑤ 系統之所以能夠根據將11個字節長度的數組正確的分成`??a夢?`,是因為在編碼時可能有以下規則: ? ascii編碼中使用了 0 - 127,即 0000 0000 - 0111 1111 。它們的共同特點是:第1位是0。 ? 再做字符串轉換時,發現第1位為0,則表示其為ascii編碼。該字符的字長為1個字節。 ? 再做字符串轉換時,發現前綴為110,則表示該編碼的字長為2個字節。 ? 再做字符串轉換時, 發面前綴為1110時,則表示該編碼的字長為3個字符。 ? 再做字符串轉換時, 發面前綴為11110時,則表示該編碼的字長為4個字符。 ![](https://img.kancloud.cn/f6/fa/f6faa6408fef0315dddaa0f4fc149c07_304x400.png) # 參考文檔 | 名稱 | 鏈接 | 預計學習時長(分) | | --- | --- | --- | | angular http 請求 | [https://www.angular.cn/guide/http](https://www.angular.cn/guide/http) | 15 | | onInit | [https://www.angular.cn/guide/lifecycle-hooks#oninit](https://www.angular.cn/guide/lifecycle-hooks#oninit) | 10 | | 箭頭函數 | [http://es6.ruanyifeng.com/#docs/function#%E7%AE%AD%E5%A4%B4%E5%87%BD%E6%95%B0](http://es6.ruanyifeng.com/#docs/function#%E7%AE%AD%E5%A4%B4%E5%87%BD%E6%95%B0) | 30 | | Enabling Cross Origin Requests for a RESTful Web Service | [https://spring.io/guides/gs/rest-service-cors/](https://spring.io/guides/gs/rest-service-cors/) | 15 | | 源碼 | https://github.com/mengyunzhi/spring-boot-and-angular-guild/releases/tag/step2.2.4 |
                  <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>

                              哎呀哎呀视频在线观看