【问题标题】:string interpolation not updating the value from service字符串插值不更新服务中的值
【发布时间】:2021-05-03 13:05:17
【问题描述】:

我有一个简单的组件来测试字符串插值。在html中,

<p>{{value}}</p>

ts 文件:

export class HelloComponent implements OnInit {
   value: any;
   constructor(private service: ApiService) {
        this.value = 'test';
   }
   ngOnInit() {
       this.getValue();
   }
   getValue = (): void => {
       this.value = this.service.getValue();
   }

既然我已经注入了服务,那么让我们来看看吧。

@Injectable({
    providedIn: 'root'
})
export  class ApiService {
      url: string;
      value: any;
      constructor(private http: HttpClient) {
           this.url = 'http://localhost:8080/api/test';
      }
      getValue = () => {
          this.http.get(this.url, {responseType: 'text'}).pipe(take(1)).subscribe(
                  data => {
                      this.value = data;
                      console.log(data); // 'Hello World' is printed out.
                      return data;
                  }
          );
      }
 }

我的问题是我可以在控制台日志中看到正确的值。但我无法获得组件中的值。它是未定义的值,所以在屏幕上它什么都不是。

【问题讨论】:

    标签: angular


    【解决方案1】:

    这不是使用 observables 获取异步数据的工作方式。您可以从服务中返回 observable 并在需要数据的地方订阅。

    服务

    @Injectable({ providedIn: 'root' })
    export class ApiService {
      url: string;
    
      constructor(private http: HttpClient) {
        this.url = 'http://localhost:8080/api/test';
      }
    
      getValue(): Observable<any> {
        return this.http.get(this.url, { responseType: 'text' })
      }
    }
    

    组件

    export class HelloComponent implements OnInit {
       value: any;
     
       constructor(private service: ApiService) {
          this.value = 'test';
       }
     
       ngOnInit() {
          this.getValue();
       }
     
       getValue(): void {
          this.service.getValue().subscribe({
            next: data => this.value = data,
            error: error { }
          });
       }
    }
    

    请完整阅读this answer 以了解您的方法为何不起作用。

    更新:关闭开放订阅

    正如我在评论中提到的,Angular HTTP observables 在单次发射后完成。所以take(1) 是多余的。但是,您可以将订阅分配给一个变量并在其上调用 .unsubscribe() 或使用 takeUntil()

    我更喜欢 takeUntil() 运算符,因为它可以用于通过一次推送到可观察对象来关闭多个订阅。

    import { Subject } from 'rxjs';
    import { takeUntil } from 'rxjs/operators';
    
    export class HelloComponent implements OnInit, OnDestroy {
       value: any;
       close$ = new Subject<any>();
     
       constructor(private service: ApiService) {
          this.value = 'test';
       }
     
       ngOnInit() {
          this.getValue();
    
          this.getOtherValue();  // <-- illustration
       }
     
       getValue(): void {
          this.service.getValue().pipe(
            takeUntil(this.close$)    // <-- close stream when `close$` emits
          ).subscribe({
            next: data => this.value = data,
            error: error { }
          });
       }
    
       getOtherValue(): void {  // <-- illustration
          this.service.getOtherValue().pipe(
            takeUntil(this.close$)    // <-- close stream when `close$` emits
          ).subscribe();
       }
    
       ngOnDestroy() {
         this.close$.next();    // <-- close both open subscriptions
       }
    }
    

    您可以参考this post 了解更简洁的方法来关闭开放订阅。

    【讨论】:

    • 它有效。我可以在这里应用 pipe 和 take(1) 来取消订阅吗?
    • 另一件事是我从服务中删除了 ` {responseType: 'text'}` 然后它停止工作。
    • 更新了退订答案@Hello
    • @你好它仍在等待批准
    • @Hello:Angular HTTP observables 在单次发射后完成。所以take(1) 是多余的。但是,您可以将订阅分配给一个变量并调用.unsubscribe() 或使用takeUntil()。我已经更新了帖子。
    猜你喜欢
    • 2017-09-29
    • 1970-01-01
    • 2022-08-11
    • 1970-01-01
    • 2017-11-06
    • 1970-01-01
    • 2021-12-10
    • 2020-01-11
    • 1970-01-01
    相关资源
    最近更新 更多