2016-12-02 54 views
2

實際上我面臨兩個挑戰。我正在循環訪問一組值並需要Angular2:從Observable設置CSS類

  1. 根據子組件 中的可觀察變量設置類名。
  2. 只要child變量發生變化,就重新評估類。

location.component.ts

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

import { BusinessLocation, SpecialDays, RegularHours } from './location'; 
import { DbService } from './db-service.component'; 

@Component({ 
    selector: '[data-locations]', 
    templateUrl: 'app/location.component.html', 
    providers: [DbService] 
}) 

export class LocationComponent { 

    locations:BusinessLocation[]; 
    selectedLocationId:Number; 
    constructor(private api:DbService){} 

    isOpenOnDay(day):Boolean { 

     let _weekDay = day.getDay(); 
     let _retour = false; 

     this.locations.forEach(loc => { 
     if (loc.id == this.selectedLocationId && loc.regularHours.weekDay == _weekDay) { 
      _retour = true; 
     } 
     }); 

     this.locations.forEach(loc => { 
     if (loc.id == this.selectedLocationId && loc.specialDays.singleDate.getDay() == _weekDay) { 
      _retour = true; 
     } 
     }); 

     return _retour; 
    } 

    getLocation():Number { 
     return this.selectedLocationId; 
    } 

    setLocation(id):void { 
     this.selectedLocationId = id; 
    } 

    getLocations():void { 
     this.api.getLocations().subscribe(
      locations => { 
      this.locations = locations as BusinessLocation[]; 
      this.setLocation(this.locations[0].id); 
      } 
     ); 
    } 

} 

DB-services.component.ts

getLocations():Observable<BusinessLocation[]> { 
     return this.http.get(this.apiUrl + '/get_locations.php') 
         .map(response => response.json().data as BusinessLocation[]); 
    } 
} 

這一切工作正常片段。然而,這就是挑戰所在。父組件啓動位置,但它也需要知道現在選擇的位置。這裏是month.component.html

<span class="location-container" #location data-locations><span class="loading">Loading locations...</span></span> 

     <div *ngFor="let day of week.days" class="day" data-can-drop="day" 
      [class.today]="isToday(day)" 
      [class.in-other-month]="day.getMonth() != jsMonth" 
      [class.is-closed]="!isOpenAtLocation(day)"> 
      <div class="day-marker"></div> 
      <span class="day-date">{{day | date:'d'}}</span> 
      <span *ngIf="checkMonth(day)" class="day-month">{{months[day.getMonth()]}}</span> 
     </div> 

month.component.ts片段被

@ViewChild('location') locationComponent:LocationComponent; 

    isOpenAtLocation(day):Boolean { 
    return this.locationComponent.isOpenOnDay(day); 
    } 

    ngOnInit(): void { 
    this.locationComponent.getLocations(); 
} 

我得到的錯誤是非常簡單,完全可以理解的:

Subscriber.ts:238 TypeError: Cannot read property 'forEach' of undefined 
    at LocationComponent.isOpenOnDay (location.component.ts:25) 
    at MonthComponent.isOpenAtLocation (month.component.ts:176) 

這就是挑戰1.挑戰2還沒有得到解決。

我只是無法環繞它。 > _ < 謝謝。

回答

1

嗯,這是一個壞的笑話在我身邊。首先,這是一個提醒,如果存在可用的綁定,則對象的屬性更改將在DOM中反映出來。所以與[class.isOpenOnDay]="day.isOpenAtLocation"將是完全足夠的,其中day是一個對象和isOpenAtLocation是它的屬性。即使它最初沒有設置(意思是它是null),並且將來會更新 - 這一切都很好。這基本上是NG的工作原理(並且一直工作)。傻我。

另一個問題 - 根據子組件變量更改值 - 已通過發出事件(來自子項),偵聽事件(父項)以及再次重置屬性isOpenAtLocation解決。

所以更新的子組件location.component.ts已更新這樣的:

@Output() locationChanged = new EventEmitter<Number>(); 

setLocation(id):void { 
    this.selectedLocationId = id; 
    this.locationChanged.emit(this.selectedLocationId); 
} 

的位置組件視圖現在有這樣一行:

<select (change)="setLocation($event.target.value)"> 
<option *ngFor="let loc of locations" value="{{loc.id}}">{{loc.longName}}</option> 
</select> 

父組件觀點必然會出現這樣的事件:

<span class="location-container" #location data-locations (locationChanged)="onLocationChange($event)"><span class="loading">Loading locations...</span></span> 

和父母month.component。TS本身有兩個方法:

onLocationChange(event) { 
    if (this.selectedLocationId != event) { 
     this.selectedLocationId = event; 
     this.setLocation(); 
     this.dispatchResize(); 
    } 
    } 

    setLocation():void { 

    if (this.selectedLocationId >= 0) { 

     for (let i = 0; i < this.weeks.length; i++) { 
     let _week = this.weeks[i]; 

     _week.forEach(_day => { 
      let _isOpen = this.locationComponent.isOpenOnDay(_day.date); 
      _day['isOpenOnDay'] = _isOpen.isOpenOnDay; 
      _day['isSpecialDay'] = _isOpen.isSpecialDay; 
      _day['dayHours'] = _isOpen.dayHours; 
     }); 

     } 

    } 

    } 

正如人們所看到的,我已經添加了更多動態檢查的屬性,不僅僅是isOpenOnDay,也isSpecialDay和dayHours,這是沒有定義開始,但被設置爲一旦數據可用 - 並且一旦發生變化就會反映在視圖中。

基本的東西,實際上。對於像我這樣的NG2 noob,可能會有所幫助。