【问题标题】:Set global variable of class from inside a promise Angular 2从 Promise Angular 2 内部设置类的全局变量
【发布时间】:2017-04-05 23:59:46
【问题描述】:

在从可观察对象内部分配对类的全局变量的响应时,我遇到了一个奇怪的问题。所以我的程序逻辑如下:

  1. 从弹性搜索中获取最新的播放列表 ID(我使用类型定义文件中的弹性搜索)。这会返回给我一个 PromiseLike,我将一个 then 运算符连接到该 PromiseLike。

  2. 在 promise 解决方案中,我进行了另一个 http get 调用(即 observable)

  3. 在 Observable 订阅中,我将来自服务器的响应分配给我的全局数组。

代码工作正常,我得到了应有的响应,但我无法将变量分配给全局变量。

这是我的代码:

import {Component, OnInit} from '@angular/core';
import {PlaylistService} from '../api/services'

@Component({
    selector: 'app-playlists',
    templateUrl: './playlists.component.html',
    styleUrls: ['./playlists.component.css']
})
export class PlaylistsComponent implements OnInit {
    public playlists: any[] = [];

    constructor(private playlistService: PlaylistService) {

    }

    ngOnInit() {
        let that = this;
        this.playlistService.listIds().then((val) => { // <-- promise resolution
            return this.playlistService.getByIds(val).toPromise(); // <-- http get call which i then convert to promise for simplicity
        }).then((res) => {  // <-- resolution of the http get call
            console.log(this.playlists); <-- in this log, i get my desired results
            // here is my problem, this assignment doesn't happens
            this.playlists = res.data;  
        });
    }
}

listIds函数如下:

listIds() {
    return this.api.listing('playlist').then((body) => {
      let hits = body.hits.hits;
      return _.keys(_.groupBy(hits, '_id'));
    });
}

这是我的 api.listing 函数(弹性搜索客户端)

listing(type: string) {
    let es = this.prepareES();
    return es.search({
            index: 'test',
            _source: ["_id"],
            type: type
    });
}

es.search的返回类型是

搜索(参数:SearchParams):PromiseLike>;

任何想法为什么我不能为全局变量赋值?

【问题讨论】:

    标签: javascript angular promise rxjs es6-promise


    【解决方案1】:

    看起来this.playlistservice.listIds() 返回的承诺不在 Angulars 区域内运行。这就是为什么 Angular2 不运行更改检测并且无法识别更改的原因。

    您可以在更改后显式调用更改检测:

     constructor(private playlistService: PlaylistService, private cdRef:ChangeDetectorRef) {
    

    ...

       ngOnInit() {
            let that = this;
            this.playlistService.listIds().then((val) => { // <-- promise resolution
                return this.playlistService.getByIds(val).toPromise(); // <-- http get call which i then convert to promise for simplicity
            }).then((res) => {  // <-- resolution of the http get call
                console.log(this.playlists); <-- in this log, i get my desired results
                // here is my problem, this assignment doesn't happens
                this.playlists = res.data; 
                this.cdRef.detectChanges(); 
            });
        }
    

    【讨论】:

    • 让我检查一下
    • 我添加了明确的更改检测后,一切正常,感谢您的帮助,在这个问题上卡住了 2 天
    【解决方案2】:

    你能不能尝试通过

    this.playlistService.listIds() 
    

    在你的内部调用

    return this.playlistService.getByIds(val)
    

    用第一个服务调用替换 val 并查看您的视图是否得到更新。仅用于测试目的,例如

    return this.playlistService.getByIds(this.playlistService.listIds())
           .then((results)=>{/*rest of logic here*/});
    

    【讨论】:

    • function(results) 应该是 (results)=&gt; 否则他根本不会得到设置的值 ;-)
    • 顺便问一下@GünterZöchbauer,您对此有何看法?我的意思是这样做是否正确?
    • @noor 因为你提到我提出的解决方案解决了你的问题,所以这不是关于价值没有改变,而是关于 Angular 没有认识到改变。因此,我认为这不会改变任何事情。另一种方法是使用zone.run(/* code that changes model here */),这也会在传递的函数完成时引起更改检测。如果更改修改了多个组件,则首选此方法,例如,如果您从运行在 angulars 区域之外的回调执行 this.router.navigate()
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-29
    • 1970-01-01
    相关资源
    最近更新 更多