【问题标题】:Why does my angular app update result only if I resize my screen?为什么我的 Angular 应用程序只有在我调整屏幕大小时才会更新?
【发布时间】:2023-03-23 06:30:01
【问题描述】:

我 3 天前开始使用 Angular 和反应式编程,所以我是这项技术的新手。

我已经成功实现了一个 Spring Boot 后端服务器,它将通过标签给我推文。

现在我正在尝试为我的通量上收到的每条消息显示一个元素到我的角度应用程序中的列表组件。

我已成功登录到控制台搜索结果,但我的 ngFor 无法正常工作......我不知道我在哪里错过了良好的做法。

这是我的 Angular 应用实现

我的反应式推特服务:

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>

我正在观看很多教程,但我不知道为什么我在我的控制台上获取数据而不是在我的阵列中?我觉得我使用 observables 的方式是错误的,但老实说我并没有很好地理解它们。

我做错了什么?以及如何解决?

更新

不小心调整了屏幕大小,数据显示出来了,为什么?

这是我的 html 内容调整前后的图片

之后

谢谢

完整项目github repository

【问题讨论】:

  • w3-ul CSS 类是如何定义的?
  • 我在索引中添加了 w3c 样式表
  • 好的。但是 w3-ul CSS 类的定义是什么?贴出它的代码。
  • 我不知道,因为它是这个框架的一部分w3schools.com/w3css/w3css_lists.asp
  • 所以您正在使用 CSS 类,但您不知道它的作用?去掉它。在浏览器中禁用 CSS,然后告诉我们会发生什么。

标签: angular rxjs observable angular-components


【解决方案1】:

在 Angular 中,我们需要通过调用 changeDetectorRef.detectChanges() 来手动触发变更检测,或者您可以将主题/行为主题与异步 observable 一起使用。

方法一:

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

方法二:

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>

【讨论】:

  • 这是不正确的。 stackblitz.com/edit/…
  • 还是不正确。正如我的示例所示,您不需要手动触发更改检测。除非您明确禁用自动更改检测,否则您基本上不必这样做。
  • 在某些情况下我们需要触发,因为我们没有完整的代码库。如果你 tel 不需要触发,那为什么 ngFor 在上面不起作用?
  • 它正在工作,因为 OP 在调整页面大小后确实会看到结果。这很可能是一个 CSS 问题,它隐藏了给定宽度以下(或给定宽度以上)的东西。
  • 这不是 CSS 问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-01-07
  • 2022-01-17
  • 1970-01-01
  • 2020-04-25
  • 1970-01-01
  • 2018-03-03
  • 2020-12-24
相关资源
最近更新 更多