最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Angular2學習教程之ng中變更檢測問題詳解

 更新時間:2017年05月28日 16:50:46   作者:panode  
這篇文章主要給大家介紹了Angular2學習教程之ng中變更檢測問題的相關資料,文中介紹的非常詳細,對大家具有一定的參考學習價值,需要的朋友們下面來一起看看吧。

開發(fā)中遇到的問題

在開發(fā)中遇到一個這樣的問題,代碼不便透露,這里用簡單的例子還原一下問題所在:

有三個組件,第一個是用來展示Todo列表的組件TodoComponent,Todo是個類,包含id和name屬性。

@Component({
 selector: 'todo-list',
 template: `
  <p *ngFor='let item of todos'>{{ item.name }}</p>
 `,
})
export class TodoComponent{
 @Input() todos: Todo[];

 public getTodos():Todo[]{
  return this.todos;
 }
}

第二個組件同樣是一個Todo列表展示組件TodoDataComponent ,不同的是該組件需要一個TodoComponent類型的輸入,并從TodoComponent組件中獲得需要展示的Todo數(shù)據(jù)。

@Component({
 selector: 'app-todo-data',
 template: `<p *ngFor='let item of todos'>{{ item.name }}</p>
  <button (click)='getData()'>get data</button>`,
 styleUrls: ['./todo-data.component.css'],
 inputs: ['todoComponent'],
})
export class TodoDataComponent implements OnInit {
 todoComponent: TodoComponent;
 todos: Todo[]
 constructor() { }
 ngOnInit() {
 }
 getData(){
  this.todos=this.todoComponent.getTodos();
 }
}

最后一個是應用的根組件,根組件根據(jù)loading值來確定是否加載TodoComponent組件,并展示TodoDataComponent 組件。

//app.component.htm
<div>
 <div *ngIf='loading'>
  <todo-list [todos]='todos'></todo-list>
  <button (click)='changeall()'>next</button>
 </div>
</div>
<div>
 <app-todo-data [todoComponent]='todoComponent'></app-todo-data>
</div>

//app.component.ts
@Component({
 selector: 'app-root',
 templateUrl: './app.component.html',
 styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
 todos: Todo[];
 @ViewChild(TodoComponent)
 todoComponent: TodoComponent;
 loading: boolean = true;
 constructor(private todoService:TodoService){
  super(true);
 }
 ngOnInit(){
  this.todoService.todos.subscribe(data => {this.todos=data});
  this.todoService.load(0, 3);
 }
 changeall(){
  this.todoService.load(3, 3);
 }
}

這樣問題就來了,TodoComponent 組件是否在頁面上展示是不確定的,在上面的例子中根組件最開始沒有渲染TodoComponent組件,最后根據(jù)loading的值將TodoComponent渲染出來。而TodoDataComponent 組件的顯示又需要一個TodoComponent 進行初始化(跟組件通過@ViewChild(TodoComponent)獲得),這樣造成在開發(fā)模式下出現(xiàn)以下錯誤:
template:9:16 caused by: Expression has changed after it was checked. Previous value: 'undefined'. Current value: '[object Object]'.

該錯誤僅在開發(fā)模式下會報告出來的,解決掉總是更好的選擇,防止在生產(chǎn)環(huán)境下出現(xiàn)問題。

問題的原因及解決辦法

這個問題是ng2中的變更檢測策略造成的,ng2并沒有智能到一有數(shù)據(jù)變更就能自動檢測到的,執(zhí)行變更檢測的一些情況有:組件中的輸入發(fā)生變化、組件中有事件響應、setTimeOut函數(shù)等。

這樣在上面的小例子中, @ViewChild(TodoComponent)todoComponent: TodoComponent;從undefined到[object Object],而并沒有觸發(fā)ng的變更檢測。

解決辦法也很簡單,ng支持手動觸發(fā)變更檢測,只要在適當?shù)奈恢茫{用變更檢測即可。
在上面的例子中,解決辦法為:

從@angular/core引入AfterViewInit, ChangeDetectorRef。注入ChangeDetectorRef對象,并在聲明周期鉤子ngAfterViewInit中調用變更

constructor(private todoService:TodoService, private cdr: ChangeDetectorRef){}

ngAfterViewInit(){
 this.cdr.detectChanges();
}

ChangeDetectorRef

用來處理ng變更的類,可以使用它來進行完全的手動變更檢測,主要有一下方法:

1.markForCheck()標記為需要進行變更檢測,官方給的一下例子,setInterval不會觸發(fā)變更檢測,因此模板上的numberOfTicks 并不會發(fā)生變化。

setInterval(() => {
this.numberOfTicks ++
 // the following is required, otherwise the view will not be updated
 this.ref.markForCheck();
}, 1000);

2.detach()從變更檢測樹上分離,即該組件不會進行自動的變更檢測,變更需要手動進行,使用detectChanges函數(shù)。

3.detectChanges()手動檢測變更,當變更檢測代價較大時,可以設置為定時進行表更檢測

ref.detach();
setInterval(() => {
 this.ref.detectChanges();
}, 5000);

4.checkNoChanges()進行變更檢測,有變更時拋出異常

5.reattach()detach()方法的作用相反

其他一些變更檢測知識

angular2中的每一個組件都關聯(lián)到一個變更檢測器,ChangeDetectorRef可以用來控制變更檢測器進行檢測。
瀏覽器的以下行為可以出發(fā)檢測器進行檢測:

1.所有瀏覽器事件

2.setTimeout()setInterval()

3.Ajax請求

OnPush變更檢測模式

組件默認使用的是Default變更檢測模式,只要組件的輸入發(fā)生變化時,就會觸發(fā)檢測器的執(zhí)行。除Default模式外,還有一種OnPush變更檢測模式,使用該模式首先需要在組件聲明修飾符中添加

@Component({
 selector: 'todo-list',
 changeDetection: ChangeDetectionStrategy.OnPush,
})

聲明為OnPush變更檢測模式意味著當組件輸入發(fā)生變化時,不一定會觸發(fā)變更檢測器,只有當該輸入的引用發(fā)生變化時,檢測器才會觸發(fā)。例如在一個數(shù)組中某個下標的值發(fā)生變化時,檢測器不會觸發(fā),視圖不會更新,只有該數(shù)組引用發(fā)生變化時,視圖才會更新。當然瀏覽器事件、observable發(fā)出的事件等還是會觸發(fā)檢測器的。

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家腳本之家的支持。

您可能感興趣的文章:

相關文章

  • Angular2學習教程之組件中的DOM操作詳解

    Angular2學習教程之組件中的DOM操作詳解

    這篇文章主要給大家介紹了Angular2學習教程之組件中DOM操作的相關資料,文中介紹的非常詳細,對大家具有一定的參考學習價值,需要的朋友們下面跟著小編一起來看看吧。
    2017-05-05
  • Angular4集成ng2-file-upload的上傳組件

    Angular4集成ng2-file-upload的上傳組件

    本篇文章主要介紹了Angular4集成ng2-file-upload的上傳組件,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-03-03
  • Angularjs實現(xiàn)數(shù)組隨機排序的方法

    Angularjs實現(xiàn)數(shù)組隨機排序的方法

    今天小編就為大家分享一篇Angularjs實現(xiàn)數(shù)組隨機排序的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-10-10
  • Angular懶加載機制刷新后無法回退的快速解決方法

    Angular懶加載機制刷新后無法回退的快速解決方法

    使用oclazyload懶加載angular的模塊,刷新頁面后,單擊回退按鈕無法返回上一個頁面.怎么回事呢?下面小編給大家?guī)砹薬ngular懶加載機制刷新后無法回退的快速解決方法,非常不錯,感興趣的朋友參考下
    2016-08-08
  • Angular中使用ng-zorro圖標庫部分圖標不能正常顯示問題

    Angular中使用ng-zorro圖標庫部分圖標不能正常顯示問題

    這篇文章主要介紹了Angular中使用ng-zorro圖標庫部分圖標不能正常顯示問題,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-04-04
  • 使用Angular內置模塊進行HTTP請求

    使用Angular內置模塊進行HTTP請求

    這篇文章主要介紹了使用Angular內置模塊進行HTTP請求方法步驟詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-10-10
  • 模板視圖和AngularJS之間沖突的解決方法

    模板視圖和AngularJS之間沖突的解決方法

    這篇文章主要介紹了模板視圖和AngularJS之間沖突的解決方法,結合實例形式分析了AngularJS模板視圖沖突的原因并給出了2種解決方法供大家參考使用,需要的朋友可以參考下
    2016-11-11
  • 淺談Angular6的服務和依賴注入

    淺談Angular6的服務和依賴注入

    這篇文章主要介紹了淺談Angular6的服務和依賴注入,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-06-06
  • Angular 1.x個人使用的經(jīng)驗小結

    Angular 1.x個人使用的經(jīng)驗小結

    這篇文章主要給大家介紹了關于Angular 1.x個人使用的一些經(jīng)驗,屬于一些基礎入門教程,文中通過示例代碼介紹的非常詳細,對大家具有一定的參考學習價值,需要的朋友們下面來一起看看吧。
    2017-07-07
  • 詳解Angular操作cookies方法

    詳解Angular操作cookies方法

    這篇文章主要介紹了詳解Angular操作cookies方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-06-06

最新評論

从化市| 高台县| 鞍山市| 南召县| 肇庆市| 文成县| 苏尼特左旗| 东乌| 申扎县| 开江县| 汝城县| 辽宁省| 阿拉善盟| 肃北| 福清市| 井研县| 罗定市| 应城市| 长沙市| 北流市| 中宁县| 苗栗市| 若羌县| 喀喇| 裕民县| 陆丰市| 阳江市| 呼伦贝尔市| 澎湖县| 老河口市| 上高县| 辽宁省| 武胜县| 黔东| 博爱县| 灵丘县| 定西市| 遵义县| 清徐县| 都江堰市| 砀山县|