2016-12-02 73 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,可能会有所帮助。