@Masterstvo

Как заставить отрендереться компонент в Angular 2, если автоматически проверка не перерендеривается?

Добрый день!

Есть компонент:
import { Component, OnInit} from '@angular/core';
import { ModuleDataService } from '../../service/data-all.service';

@Component({
    moduleId: module.id,
    selector: 'bottom-panel',
    templateUrl: './bottom-panel.html',
    styleUrls: ['bottom-panel.css']
})
export class BottomPanel implements OnInit{

    visiblePanel: any;

    constructor(private dataAll: ModuleDataService){}

    ngOnInit(){
        this.visiblePanel = this.dataAll.getDataBottomPanel();
        console.log(this.visiblePanel);
    }
}


Темплейт для компонента:
<section class="prev-calculate" *ngIf="visiblePanel">
    <div class="container">
        <div class="prev-calculate-box">
            <div class="calculate-range">
                <div class="calculate-range-title">Диапазон цен</div>
                <div class="price-before">32 400</div><span class="deffis">—</span>
                <div class="price-after">56 500</div>
            </div>
            <div class="btn-go-to-next">Перейти к выбору исполнителя</div>
        </div>
    </div>
</section>


Есть сервис, который предоставляет данные и манипулирует логикой:
export class ModuleDataService {

    public state: boolean = false;

    getDataBottomPanel(){
        return this.state;
    }
   
    // Метод который срабатывает при событии на каком-нибудь компоненте и изменяет переменную state
    toggle(){
    ...
       this.state = !this.state;
    ...
    }
}


Задача то в принципе простая, нужно вывести что-то типа popup окна при событии на одном из существующих компонентов, изменить свойство state и отобразить компонент bottom-panel. State в результате события изменяется, но Angular не хочет отображать этот компонент. Что я делаю не так? Можно ли как то по другому сделать данную операцию? Заранее спасибо!!!!
  • Вопрос задан
  • 181 просмотр
Пригласить эксперта
Ответы на вопрос 2
Ну вы же понимаете, что компонент не знает о том, что в сервисе что-то поменялось?
Ответ написан
ozknemoy
@ozknemoy
яваскриптист
чтобы компонент знал что в сервисе что то изменилось нужно подписаться(либо отнаследоваться). у меня есть сервис который создает подписчика на событие. аналог $on +$emit/$broadcast из первой версии. там есть просто пример(который закомментирован) и конструктор который может создавать любый подписчики

import { Observable } from 'rxjs/Observable';
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import {HttpService} from "../modules/transfer-http/transfer-http";

@Injectable()
export class SharedService {

    constructor(public httpService:HttpService) {}

    /* это просто для примера для удобства понимания что делать
    private emitMessageSource;
    public messageListener$;
    public emitMessage;

    makeMessageListener() {
        this.emitMessageSource = new Subject<any>();
        this.messageListener$ = this.emitMessageSource.asObservable();
        this.emitMessage = (newValue: any) => {
            this.emitMessageSource.next(newValue);
        }
    }
    killMessageListener() {
        this.emitMessageSource = undefined;
        this.messageListener$ = undefined;
        this.emitMessage = undefined
    }*/

    // 1)в родителе создать слушателя:
    // var name = 'Message'; this.sharedService.makeProxy(name);
    // 2)подписаться: this.message$ = this.sharedService[name + 'Listener$'].subscribe(text => {console.log(text);});
    // 3)в ребенке:  отослать данные this.sharedService['emit' + 'Message']('Data from child');
    // 4)в родителе не забыть убить слушателя: this.sharedService.killListener('Message')

    makeProxy(name:string,dataSubject={}) {
        /*
        * if you have a component that listens to the isLoggedIn Observable after we already
        * call the next method, with simple Observable or Subject the component will not
        * get any data. That’s why we need the BehaviorSubject
        *
        * Mark Pieszak comment
          use .share() when creating the Observable, so that your async pipes
          don’t create multiple subscriptions.
         isLoggedIn() : Observable<boolean> {
         return this.isLoginSubject.asObservable().share();
         }
        */
        this['emit' + name + 'Source'] = new BehaviorSubject<any>(dataSubject);
        // сюда подписываемся и ...
        this[name + 'Listener$'] = this['emit' + name + 'Source'].asObservable().share();
        // ... обновляем значение
        this['emit' + name] = (newValue: any) => {
            this['emit' + name + 'Source'].next(newValue);
        }
    }

    killListener(name) {
        this['emit' + name + 'Source'] = undefined;
        this[name + 'Listener$'] = undefined;
        this['emit' + name] = undefined
    }


}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы