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

                本節來完成編輯班級中的教師列表部分,編輯教師時,應當自動選中該班級對應的教師。至于應該選中哪個教師,則應該按教師`id` 進行對應。 為此,我們需要簡單改造一下MockApi。使教師列表的返回ID在1-10之間: ```typescript +++ b/first-app/src/app/mock-api/teacher.mock.api.ts @@ -1,4 +1,5 @@ import {ApiInjector, MockApiInterface, randomNumber} from '@yunzhi/ng-mock-api'; +import {randomString} from '@yunzhi/ng-mock-api/testing'; /** * 教師模擬API @@ -9,16 +10,16 @@ export class TeacherMockApi implements MockApiInterface { // 獲取所有教師 method: 'GET', url: 'teacher', - result: [ - { - id: randomNumber(), - name: '教師姓名1' - }, - { - id: randomNumber(), - name: '教師姓名2' + result: () => { + const teachers = []; + for (let i = 1; i <= 10; i++) { + teachers.push({ + id: i, + name: randomString('教師姓名') + }); } - ] + return teachers; + } }]; } } ``` 然后獲取某個班級時對應的教師ID為1至10之間的任意值: ```typescript +++ b/first-app/src/app/mock-api/clazz.mock.api.ts @@ -87,7 +87,7 @@ export class ClazzMockApi implements MockApiInterface { id, name: randomString('班級名稱'), teacher: { - id: randomNumber(), + id: randomNumber(9) + 1, name: randomString('教師') } } as Clazz; ``` ## @Input() 為教師選擇組件增加一個`@Input()`,至于該`@Input()`是注解到屬性還是`set`方法上,則當前應該看具體的場景: 1. 如果考慮父組件對應子組件上輸入數值的變化,則應該注解到`set`方法上。 2. 如果不考慮父組件上的數值變化對子組件的影響,則應該注解到屬性上。 對于當前情景而言,父組件對子組件設置的教師id的值是通過請求后臺數據后獲取到的。執行過程大體如下: 1. 父組件初始化 2. 父組件請求后臺班級數據,此時班級數據為空,班級對應的教師數據當然也為空。 3. 子組件初始化,綁定`@Input`. 4. 父組件的請求得到了響應,此時獲取了班級數據,獲取到了班級對應的教師數據,需要重新對子組件`@Input()` 進行設置。 所以教師選擇組件更適合于將`@Input()`注解到`set`方法上: ```typescript +++ b/first-app/src/app/clazz/klass-select/klass-select.component.ts + @Input() + set id(id: number) { + // 使用接收到的id設置teacherId + this.teacherId.setValue(id); + } + ``` ## 測試 我們仍在其父班級編輯組件中對子組件進行測試。為此,需要在父組件中傳入這個`id`屬性: ```typescript +++ b/first-app/src/app/clazz/edit/edit.component.html @@ -12,7 +12,7 @@ <div class="mb-3 row"> <label class="col-sm-2 col-form-label">班主任</label> <div class="col-sm-10"> - <app-klass-select></app-klass-select> + <app-klass-select [id]="teacherId"></app-klass-select> <small class="text-danger"> 必須指定一個班主任 </small> ``` C層中增加`teacherId`,初始化并賦值: ```typescript +++ b/first-app/src/app/clazz/edit/edit.component.ts @@ -14,6 +14,7 @@ export class EditComponent implements OnInit { * 班級名稱. */ nameFormControl = new FormControl('', Validators.required); + teacherId: number | undefined; constructor(private activatedRoute: ActivatedRoute, private httpClient: HttpClient) { @@ -34,6 +35,7 @@ export class EditComponent implements OnInit { .subscribe(clazz => { console.log('接收到了clazz', clazz); this.nameFormControl.patchValue(clazz.name); + this.teacherId = clazz.teacher.id; }, error => console.log(error)); } ``` 測試結果: ![image-20210402153955072](https://img.kancloud.cn/fe/5e/fe5e81aec86e90026b72f5836679bf95_2416x456.png) ## @Output() 輸入完成后,再增加一個輸出對接: ```typescript +++ b/first-app/src/app/clazz/edit/edit.component.html @@ -12,7 +12,7 @@ <div class="mb-3 row"> <label class="col-sm-2 col-form-label">班主任</label> <div class="col-sm-10"> - <app-klass-select [id]="teacherId"></app-klass-select> + <app-klass-select [id]="teacherId" (beChange)="onTeacherChange($event)"></app-klass-select> <small class="text-danger"> 必須指定一個班主任 </small> ``` 對應增加C層的方法: ```typescript +++ b/first-app/src/app/clazz/edit/edit.component.ts @@ -39,4 +39,8 @@ export class EditComponent implements OnInit { }, error => console.log(error)); } + onTeacherChange($event: number): void { + console.log('接收到了選擇的teacherId', $event); + this.teacherId = $event; + } ``` 測試效果: ![image-20210402154452053](https://img.kancloud.cn/64/a8/64a88f1d7ecfbf04b4848f0efc561cb1_1090x216.png) 每點擊一個教師后C層的方法都會被觸發一次,有意思的是組件初始化時,我們并沒有點擊教師列表,但父組件的`onTeacherChange`方法也被調用了一次。 這是由于在初始化時教師選擇組件中的執行順序如下: 1. 班級編輯組件初始化,teacherId為undefined,異步請求數據開始。 2. 教師選擇組件初始化,執行`set id(undefined)`方法,調用`teacherId`的`setValue()`方法。 3. 執行教師選擇組件的`ngOnInit()`方法,在該方法中對`teacherId`的數值變更進行了訂閱,此后`teacherId`再有新值時,將得到一個通知。得到通知后將向父組件彈出得到的`teacherId`。 4. 父組件的異步請求數據返回,再次調用教師選擇組件的`set id(xx)`方法,調用`teacherId`的`setValue()`方法。此時在3中的訂閱將得到一個通知,近而向父組件彈出得到的teacherId。 5. 父組件接收到`teacherId`后,打印在控制臺,組件初始化完畢。 上述流程導致了在初始化父組件將某個`teacherId`傳給子組件后,子組件又將其傳回了父組件。這雖然無關緊要,但的確是個多余的操作。 ## 加入驗證 最后我們加入對班主任的驗證,未設置班主任時顯示相關的錯誤信息: ```html +++ b/first-app/src/app/clazz/edit/edit.component.html @@ -13,7 +13,7 @@ <label class="col-sm-2 col-form-label">班主任</label> <div class="col-sm-10"> <app-klass-select [id]="teacherId" (beChange)="onTeacherChange($event)"></app-klass-select> - <small class="text-danger"> + <small class="text-danger" *ngIf="teacherId === undefined"> 必須指定一個班主任 </small> </div> ``` 再次測試,錯誤消失: ![image-20210402160102894](https://img.kancloud.cn/5c/4c/5c4c6ba92091ad44c49553eaa6a5184a_2264x234.png) ## 本節作業 嘗試在教師選擇組件中,引入一個緩存變量`idInput` ,并使用其來規避在組件初始化時彈出的多余數據。 | 名稱 | 鏈接 | | -------- | ------------------------------------------------------------ | | 本節源碼 | [https://github.com/mengyunzhi/angular11-guild/archive/step6.4.3.zip](https://github.com/mengyunzhi/angular11-guild/archive/step6.4.3.zip) |
                  <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>

                              哎呀哎呀视频在线观看