M
M
Masterstvo2017-06-14 19:08:29
Angular
Masterstvo, 2017-06-14 19:08:29

How to force a component to be rendered in Angular 2 if validation is not automatically re-rendered?

Good afternoon!
There is a component:

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);
    }
}

Template for the component:
<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>

There is a service that provides data and manipulates logic:
export class ModuleDataService {

    public state: boolean = false;

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

The task is basically simple, you need to display something like a popup window when an event occurs on one of the existing components, change the state property and display the bottom-panel component. The state changes as a result of the event, but Angular doesn't want to render this component. What am I doing wrong? Is there any other way to do this operation? Thanks in advance!!!!

Answer the question

In order to leave comments, you need to log in

2 answer(s)
N
Nicholas, 2017-06-14
@healqq

Well, you understand that the component does not know that something has changed in the service, right?

O
ozknemoy, 2017-06-14
@ozknemoy

so that the component knows that something has changed in the service, you need to subscribe (or inherit). I have a service that creates an event subscriber. analogue of $on +$emit/$broadcast from the first version. there is just an example (which is commented out) and a constructor that any subscribers can create

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
    }


}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question