【问题标题】:Angular2: Set CSS class from ObservableAngular2:从 Observable 设置 CSS 类
【发布时间】:2016-12-06 02:05:18
【问题描述】:

实际上我面临两个挑战。我正在循环一个值数组,需要

  1. 根据孩子的可观察变量设置类名 零件。
  2. 一旦子变量发生变化,就重新评估类。

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

的 sn-p
    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 的 sn-p 是

  @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 甚至还没有解决。

我就是想不通。 >_

【问题讨论】:

    标签: css angular typescript promise observable


    【解决方案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 菜鸟还是有帮助的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-26
      • 2021-10-11
      • 2016-08-07
      • 2017-01-04
      • 2010-09-23
      相关资源
      最近更新 更多