Angular 2 Наблюдаемое выпадение из угловой зоны

Приложение Angular 2, в котором большая часть приложения находится в службах @Injectable, которые отображают состояние через Observable. В какой-то момент приложение выпадает из угловой зоны, что приводит к тому, что обнаружение изменений не работает. В моей подписке мне нужно позвонить ChangeDetectorRef.detectChanges() когда это произойдет. Как убедиться, что приложение не выпадает из угловой зоны? Или определить, что вызывает это?

Вот мой сервис:

@Injectable()
export class CalendarFilterStore {
    private currentState: CalendarFilter;
    private state$ = new ReplaySubject<CalendarFilter>(1);

    constructor() {
        this.currentState = {
            startDate: new Date(2016, 10, 14, 2)
        };
        this.state$.next(this.currentState);
    }

    get state(): Observable<CalendarFilter> {
        console.log('calendar filter state, zone: ' + Zone.current.name);
        return this.state$.asObservable();
    }

Вот функция ngOnInit для компонента, который использует этот сервис:

ngOnInit() {
    console.log('ng init zone: ' + Zone.current.name);
    this.calendarFilterStore.state
        .filter(state => {
            console.log('got filter state, zone: ' + Zone.current.name);
            return (state.areaIDs !== undefined && state.worksiteID !== undefined && state.startDate !== undefined && state.numberOfShifts !== undefined);
        })
        .switchMap(state => this.getCalendar(state))
        .subscribe(res => {
            console.log('got calendar, dashboard-table, zone: ' + Zone.current.name);
            this.loadCalendar(res);
        }, error => {
            console.log(error);
        });

Вот вывод консоли, который показывает, когда мы выпадаем из угловой зоны. Похоже, это происходит, когда фильтр календаря испускает свое второе значение.

calendar filter state, zone: angular
calendar-filter - store.ts:21 calendar filter state, zone: angular
calendar-store.ts:22 get calendar state, zone: angular
dashboard-table.component.ts:60 ng init zone: angular
calendar-filter - store.ts:21 calendar filter state, zone: angular
dashboard-table.component.ts:63 got filter state, zone: angular
dashboard-table.component.ts:63 got filter state, zone: <root>
dashboard-table.component.ts:63 got filter state, zone: <root>
calendar.service.ts:25 get calendar, zone: <root>
calendar.service.ts:31 got calendar, zone: <root>
dashboard-table.component.ts:68 got calendar, dashboard-table, zone: <root>
calendar-store.ts:27 segments returned, zone: <root>

Я сузил его до компонентов, которые находятся на нескольких уровнях в глубине моего дерева компонентов. Когда я проверяю Zone.current.name в их конструкторах, они находятся в root зона, а не angular зона. Любые события, которые они излучают, остаются в root зона, даже когда они распространяются на родитель-> сервис-> подписчик.

Вот шаблон компонента, который работает и работает в угловой зоне, но его дочерний элемент, sb-worksite-selector, работает в корневой зоне, как видно из выходных данных.

<div class="dashboard-navigation" *ngIf="optionsLoaded">
  <button type="button" class="btn btn-secondary" (click)="previousDay()"><i class="fa fa-backward" aria-hidden="true"></i> Previous Day</button>
  <div class="inline-block">
      <sb-worksite-selector [worksiteOptions]="worksiteOptions"
                            (onWorksiteChanged)="worksiteChanged($event)">
      </sb-worksite-selector>
  </div>

SB-селектор строительной площадки

@Component({
    selector: 'sb-worksite-selector',
    templateUrl: 'worksite-selector.component.html',
    styleUrls: ['worksite-selector.component.scss']
})
export class WorksiteSelectorComponent implements OnInit {
    @Input() worksiteOptions: Array<any>;
    @Output() onWorksiteChanged = new EventEmitter<number>();

    constructor() {
        console.log('create worksite selector, zone: ' + Zone.current.name);
    }

    ngOnInit() {
        console.log('init worksite selector, zone: ' + Zone.current.name);
    }
}

Ведение журнала для селектора Worksite:

calendar filter state, zone: angular
dashboard - table.component.ts:63 got filter state, zone: angular
calendar.service.ts:25 get calendar, zone: angular
dashboard - navigation.component.ts:63 dashboard navigation got areas and worksites, zone: angular
worksite - selector.component.ts:14 create worksite selector, zone: <root>
worksite - selector.component.ts:18 init worksite selector, zone: <root>

0 ответов

Другие вопросы по тегам