真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Angular2之ng中變更檢測(cè)問(wèn)題的示例分析

這篇文章主要介紹Angular2之ng中變更檢測(cè)問(wèn)題的示例分析,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!

成都創(chuàng)新互聯(lián)是專業(yè)的江北網(wǎng)站建設(shè)公司,江北接單;提供網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì),網(wǎng)頁(yè)設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行江北網(wǎng)站開發(fā)網(wǎng)頁(yè)制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛(ài)的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來(lái)合作!

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

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

有三個(gè)組件,第一個(gè)是用來(lái)展示Todo列表的組件TodoComponent,Todo是個(gè)類,包含id和name屬性。

@Component({
 selector: 'todo-list',
 template: `
  {{ item.name }}

 `, }) export class TodoComponent{  @Input() todos: Todo[];  public getTodos():Todo[]{   return this.todos;  } }

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

@Component({
 selector: 'app-todo-data',
 template: `{{ item.name }}

  get data`,  styleUrls: ['./todo-data.component.css'],  inputs: ['todoComponent'], }) export class TodoDataComponent implements OnInit {  todoComponent: TodoComponent;  todos: Todo[]  constructor() { }  ngOnInit() {  }  getData(){   this.todos=this.todoComponent.getTodos();  } }

最后一個(gè)是應(yīng)用的根組件,根組件根據(jù)loading值來(lái)確定是否加載TodoComponent組件,并展示TodoDataComponent 組件。

//app.component.htm
       next  
 
//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);  } }

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

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

問(wèn)題的原因及解決辦法

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

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

解決辦法也很簡(jiǎn)單,ng支持手動(dòng)觸發(fā)變更檢測(cè),只要在適當(dāng)?shù)奈恢?,調(diào)用變更檢測(cè)即可。
在上面的例子中,解決辦法為:

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

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

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

ChangeDetectorRef

用來(lái)處理ng變更的類,可以使用它來(lái)進(jìn)行完全的手動(dòng)變更檢測(cè),主要有一下方法:

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

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

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

3.detectChanges()手動(dòng)檢測(cè)變更,當(dāng)變更檢測(cè)代價(jià)較大時(shí),可以設(shè)置為定時(shí)進(jìn)行表更檢測(cè)

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

4.checkNoChanges()進(jìn)行變更檢測(cè),有變更時(shí)拋出異常

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

其他一些變更檢測(cè)知識(shí)

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

1.所有瀏覽器事件

2.setTimeout()setInterval()

3.Ajax請(qǐng)求

OnPush變更檢測(cè)模式

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

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

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

以上是“Angular2之ng中變更檢測(cè)問(wèn)題的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!


文章題目:Angular2之ng中變更檢測(cè)問(wèn)題的示例分析
路徑分享:http://weahome.cn/article/piceoo.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部