Почему обновление моего углового приложения происходит только тогда, когда я изменяю размер экрана? - PullRequest
0 голосов
/ 09 декабря 2018

Я начал использовать угловое и реактивное программирование 3 дня назад, поэтому я новичок в этой технологии.

Я успешно внедрил бэкэнд-сервер с весенней загрузкой, который будет давать мне твиты по тегам.

Теперь я пытаюсь показать для каждого полученного сообщения на моем потоке элемент в компонент списка в моем угловом приложении.

Я успешно захожу в консоль с результатом поиска, но мой ngFor не работает... Я не знаю, где мне не хватает хорошей практики.

Вот моя угловая реализация приложения

Мой реактивный твиттер-сервис:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, of, BehaviorSubject } from 'rxjs';
import { ITweet } from './model/itweet';

@Injectable({
    providedIn: 'root'
})
export class ReactiveTwitterSpringService {

    tweetSubject = new BehaviorSubject<ITweet>(new ITweet);

    currentTweet = this.tweetSubject.asObservable();

    tweetTag: string;

    baseUrl = 'http://localhost:8081/search';

    search(tag: string) {

        const url = this.baseUrl + '/' + tag.trim().split(' ').join('_');

        return Observable.create(
            observer => {
                const enventSource = new EventSource(url);
                enventSource.onmessage = (message) => {
                    const json = JSON.parse(message.data);
                    console.log(new ITweet(json.tweetData.name, json.tweetData.text, json.tag));
                    this.tweetSubject.next(new ITweet(json.tweetData.name, json.tweetData.text, json.tag));
                    observer.next(new ITweet(json.tweetData.name, json.tweetData.text, json.tag));
                };
                enventSource.onerror = (error) => {
                    if (enventSource.readyState === 0) {
                        console.log('The stream has been closed by the server.');
                        enventSource.close();
                        observer.complete();
                    } else {
                        observer.error('EventSource error: ' + error);
                    }
                };
               return () => enventSource.close();
            }
        );
    }

    constructor() { }
}

Мойкомпонент, где у меня есть поиск и список результатов:

import { Component, OnInit } from '@angular/core';
import { BreakPointService } from '../../providers/break-point.service';
import { ReactiveTwitterSpringService } from '../../reactive/reactive-twitter-spring.service';
import { ITweet } from '../../reactive/model/itweet';
import { Subscription } from 'rxjs';

@Component({
    selector: 'app-tweet-list',
    templateUrl: './tweet-list.component.html',
    styleUrls: ['./tweet-list.component.css']
})
export class TweetListComponent implements OnInit {
    list_div_class;
    search_input_class;

    search_results: ITweet[] = new Array();
    subscribe: Subscription = new Subscription();
    constructor(private tweetService: ReactiveTwitterSpringService) { }

    search(tag) {
        this.search_results = new Array();
        this.subscribe.unsubscribe();
        this.subscribe = new Subscription();
        this.subscribe.add(this.tweetService.search(tag).subscribe(tweet => {
            this.search_results.push(tweet);
            console.log(tweet);
        }));
        console.log('array contains ' + this.search_results);
    }

    ngOnInit() {
        BreakPointService.current_css.subscribe(value => {
            console.log('value is ' + value);
            this.setupCss(JSON.parse(value));
        });
    }

    setupCss(value: any): any {
        this.list_div_class = value.list_div_class;
        this.search_input_class = value.search_input_class;
    }
}

HTML-шаблон, связанный с моим компонентом:

<div class="{{list_div_class}}">
  <input type="text" class="{{search_input_class}}" (keyup.enter)="search(searchInput.value)" #searchInput>
  <ul class="w3-ul">
    <li *ngFor="let tweet of search_results ">
        data
      <app-tweet-detail [detail]="tweet"></app-tweet-detail>
    </li>
  </ul>
</div>

Я смотрю много учебников, но я незнаете, почему я получаю данные на моей консоли, а не в моем массиве?Я чувствую, что я использую наблюдаемые неправильно, но если честно, я не очень хорошо их понял.

Что я делаю не так?И как это исправить?

Обновление

Случайно я изменил размер моего экрана и отображались данные, почему?

вот изображения моего htmlсодержание до и после изменения

before

после

after

Спасибо

Для полного проекта репозиторий github

1 Ответ

0 голосов
/ 09 декабря 2018

В Angular, нам нужно вручную запускать обнаружение изменений, вызывая changeDetectorRef.detectChanges (), или вы можете использовать субъект / поведение субъекта с наблюдаемой асинхронностью.

Подход 1:

constructor(private cdr: ChangeDetectorRef){} 
this.subscribe.add(this.tweetService.search(tag).subscribe(tweet => {
    this.search_results.push(tweet);
    this.search_results = this.search_results.slice();
    this.cdr.detectChanges();
    console.log(tweet);
}));

Подход 2:

public this.search_results$ = new Subject<any>();
this.subscribe.add(this.tweetService.search(tag).subscribe(tweet => {
    this.search_results.push(tweet);
    this.search_results$.next(this.search_results);
    console.log(tweet);
}));

Шаблон:

<li *ngFor="let tweet of search_results$ | async ">
    data
  <app-tweet-detail [detail]="tweet"></app-tweet-detail>
</li>
...