2017-02-04 39 views
1

我是Angular 2的新手,我想通過@Input()將一個在父組件中創建的數組傳遞給它的子節點。在@Input()之後,數組是否改變爲對象?

在父項中,我創建數組,從服務中添加數據並將其顯示在控制檯(控制檯輸出1)中。在子組件中,我使用ngOnChanges再次在控制檯中顯示它(控制檯輸出2)。正如你在下面看到的,數組的長度從12變爲0.我想這是因爲當數組傳遞給子對象時,數組變成了對象?

我該如何解決這個問題?

import { Component, OnInit } from '@angular/core'; 
import { Module, MapMarkerData } from './coreclasses'; 
import { TimelineService } from './input.service'; 

@Component({ 
    selector: 'my-app', 
    templateUrl: 'app/app.component.html', 
    providers: [TimelineService] 
}) 

export class AppComponent implements OnInit { 
    modules: Module[]; 
    mapMarkerData: any; 

    constructor(private timelineService: TimelineService) { 
    this.mapMarkerData = new Array<MapMarkerData>(); 
    } 

    getModules(): void { 
    this.timelineService.getModules().then(modules => {this.modules = modules; this.setMapModuleData(this.modules);}); 
    } 

    setMapModuleData(modules: Array<any>): void { 
    for (let module of modules) { 
     if (module.className) { 
     var id = module.id; 
     var className = module.className; 
     let contents: Object = {id: id, className: className}; 
     this.mapMarkerData.push(contents); 
     } 
    } 
    console.log(this.mapMarkerData); // CONSOLE OUTPUT 1 
    console.log(this.mapMarkerData.length); 
    } 
} 

兒童

import { Component, Input, OnInit, OnChanges, SimpleChanges } from '@angular/core'; 
import { MapMarkerData } from './coreclasses'; 

@Component({ 
    selector: 'timeline-map', 
    templateUrl: 'app/timeline.map.component.html' 
}) 

export class TimelineMapComponent implements OnChanges { 
    @Input() 
    mapMarkerData: any; 

    ngOnChanges(changes: any) { 
     console.log(this.mapMarkerData); // CONSOLE OUTPUT 2 
     console.log(this.mapMarkerData.length); 
    } 
} 

父模板

... 
<div id="map" class="mapLarge"> 
    <timeline-map [mapMarkerData] = "mapMarkerData"></timeline-map> 
</div> 
... 

控制檯輸出1 陣列[12]:[對象,對象,...]

控制檯輸出2 數組[0]:[對象,對象,...]

+0

傳遞給孩子當陣列沒有改變。我懷疑'Console Output 2'是在'Console Output 1'之前打印的。情況並非如此嗎? –

+0

更改由'changes.mapMarkerData.currentValue'訪問 – harshes53

回答

1

EDIT重要

,因爲你傳遞相同的成子組件,所以ngOnChanges生命週期只發射1次。

請結帳這個版本中,打開您的控制檯選項卡:https://plnkr.co/edit/WUDGOx?p=preview

所以,如果你想抓住每一個變化ngOnChanges生命週期,必須通過差異陣列,像這樣:https://plnkr.co/edit/8awiqe?p=preview

import { Component, OnInit } from '@angular/core'; 

@Component({ 
    selector: 'app-root', 
    template: ` 
    <h2>App Component</h2> 
    <p><strong>This app will trigger ngOnChanges with immutable array</strong></p> 
    <app-content [posts]="posts"> 
    </app-content> 
    ` 
}) 
export class AppComponent implements OnInit { 
    latestPosts: any[] = []; 
    posts: any[] = []; 


    ngOnInit() { 
    // fake api call 
    setTimeout(() => { 
     this.latestPosts.push.apply(this.latestPosts, [ 
     {name: 'Post no.1'}, 
     {name: 'Post no.2'}, 
     {name: 'Post no.3'} 
     ]); 
     this.posts = [].concat(this.latestPosts); 
    }, 300); 
    } 

} 

===第二選擇===你可以自己檢查DoCheck生命週期:https://plnkr.co/edit/oxsISD?p=preview

import { Component, Input, DoCheck, IterableDiffers } from '@angular/core'; 

@Component({ 
    selector: 'app-content', 
    template: ` 
    Status: {{ status }} 
    <div *ngFor="let post of pp"> 
     {{ post.name }} 
    </div> 
    ` 
}) 

export class ContentComponent implements DoCheck { 

    @Input() 
    posts: any[]; 
    differ: IterableDiffers; 
    status: string = ''; 

    constructor(private differs: IterableDiffers) { 
     this.differ = this.differs.find([]).create(null); 
    } 

    ngDoCheck() { 
    var changes = this.differ.diff(this.posts); 
    if (changes) { 
     console.log('ngDoCheck'); 
     this.status = 'ngDoCheck invoked!' 
    } 
    } 
} 

請注意,您必須支付費用,因爲上述ngDoCheck方法將在每次更改檢測運行時調用。

https://angular.io/docs/ts/latest/guide/lifecycle-hooks.html

https://angular.io/docs/ts/latest/api/core/index/DoCheck-class.html

https://angular.io/docs/ts/latest/api/core/index/SimpleChange-class.html

https://angular.io/docs/ts/latest/api/core/index/IterableDiffers-class.html

END

初始狀態,它是空的,則該值將分配給該屬性。

JS登錄異步 js log async

+0

感謝您的回覆如此之快!控制檯輸出2不是空的(參見[Object,Object,...]),它包含從父節點收到的數組的內容,但其長度在某種程度上爲零。 console.log(更改['mapMarkerData']。currentValue.length)也給出0,但我可以看到它包含數組內容,並且console.log(changes ['mapMarkerData']。previousValue)爲空,因爲它應該是。所以孩子從父母那裏收到修改後的數組,但其顯示的長度已經改變了?這對我來說真的沒有意義嗎? – Merlin

+0

hey man,這是js的方式,如果你在時間線0上空'log'數組空白,那麼時間線1,你給這個值,它會輸出長度爲0,但內容不爲空 –

+0

打開控制檯選項卡(f12) ,那麼試試這個http://jsbin.com/perujayewu/edit?js,console,output –

相關問題