【问题标题】:Angular5 - Not able to use Object.keys as expectedAngular5 - 无法按预期使用 Object.keys
【发布时间】:2018-06-22 08:08:41
【问题描述】:

我正在开发一个应用程序,从我们的私有 git 企业服务器中提取数据。我有一个字符串数组供 repos 检查,我将这些数据与本地 JSON 文件中的一些数据结合起来,给我一个如下结构:

{ 
  repo1: {},
  repo2: {},
  repo3: {}
}

对象完全按照我的预期返回。问题是我什么时候想要计数。通常在 JS 中我使用 Object.keys,但是当我这样做时它返回一个空数组。我通过创建一个本地数组并将名称推入其中暂时解决了这个问题,以便我可以使用 ngFor 进行迭代。我越深入,它就越没有意义。我可以在对象文字或我的预定义对象上毫无问题地使用 Object.keys。问题是当我尝试在这个返回的对象上使用它时。我正在运行代码以获取 ngOnInit() 中的对象。当我 console.log 对象时,它完全按预期返回,但如果我将日志更改为 Object.keys(object) 它返回空白。我认为这可能是一个时间问题,所以我将函数包装在一个 promise 中并链接了一个 .then 。同样,promise 返回的对象看起来是正确的,但我不能在其上使用 Object.keys。我也尝试返回 Object.keys(object) 而不是函数中的对象,但它仍然返回空白。

我有什么遗漏吗?有没有更“角度”的方式来处理这个问题?我使用 Angular 已经有一段时间了,但从来没有遇到过这样的事情。想知道是不是时间问题还是什么的。

tabContentSetup(tabArray) {
const filteredObject = {};
const filteredArray = [];
// For each element in the array, get the repo name
tabArray.forEach((repo) => {
  // Grab all prs for the current repo
  this.gitApiService.getPrs(repo)
    // Subscribe to observable which returns an array of PR objects from the repo
    .subscribe((prObjectArray) => {
      // Iterate over each prObject in prObjectArray
      prObjectArray.forEach((prObject) => {
        // Grab the github user that submitted PR in lowercase
        const prObjectUser = prObject.user.login.toLowerCase();
        // If this PR belongs to a consultant, disregard and return
        if (this.instructorsArray.includes(prObjectUser)) {
          return;
        }
        // If filteredObject does not have the current repo yet, add it as a new object
        if (!filteredObject[repo]) {
          filteredObject[repo] = {
            count: 1,
            cohortsArray: [],  // TODO fix this with Object.keys
            cohorts: {}
          };
          filteredArray.push(repo); // TODO find out why Object.keys isn't working
        } else {
          filteredObject[repo]['count']++; // TODO could be shortened with Object.keys
        }
        if (this.gitHubDict[prObjectUser] === undefined) {
          console.warn('Cannot find: ' + prObjectUser + ' in Cohort JSON files');
          return;
        }
        const assignedCohort = this.gitHubDict[prObjectUser].cohort;
        if (!filteredObject[repo]['cohorts'][assignedCohort]) {
          filteredObject[repo].cohortsArray.push(assignedCohort);
          filteredObject[repo]['cohorts'][assignedCohort] = {
            count: 1,
            prs: []
          };
        } else {
          filteredObject[repo]['cohorts'][assignedCohort].count++;
        }
        filteredObject[repo]['cohorts'][assignedCohort]['prs'].push({
          name: this.gitHubDict[prObjectUser].first + ' ' + this.gitHubDict[prObjectUser].last,
          cohort: assignedCohort,
          git: prObjectUser,
          url: prObject.html_url,
          created_at: prObject.created_at,
          updated_at: prObject.updated_at
        });
        });
    });
});
return Object.keys(filteredObject);
}

这太长了,这就是为什么我要回去尝试用 Object.keys 重构。

【问题讨论】:

  • 对象最初来自哪里?
  • 我在 ngOnInit() 中运行的返回对象的函数。
  • “返回对象”但是是什么创建了 那个 对象?
  • 请不要描述代码;这不起作用。该问题应包含所有相关代码。见stackoverflow.com/help/mcve
  • 已更新代码。

标签: angular object


【解决方案1】:

返回不等待订阅者,所以filteredObject 为空。您应该将 filteredObject 设为 Observable(或者更确切地说是 Subject)并订阅它。这部分代码在方法调用上按顺序执行:

const filteredObject = {};
const filteredArray = [];
tabArray.forEach((repo) => {
    this.gitApiService.getPrs(repo).subscribe();
}
return Object.keys(filteredObject);

subscribe()回调方法中的部分被执行,当getPrs()触发返回的observable中的next()时(我猜你返回HttpClient.get()?)。因此,在调用tabContentSetup() 时,它将返回一个空对象,因为 HTTP 请求尚未完成。

我建议使用 BehaviorSubject(请参阅此答案:BehaviorSubject vs Observable?)。在函数之外声明 filteredObject 并使用它内置的 getter .value 和“setter” .next()

// initialize a Subject with an empty object
filteredObjectObservable = new BehaviorSubject({});
// initialize a public variable for the count
repoCount: number;

tabContentSetup(tabArray) {
    tabArray.forEach((repo) => {
        this.gitApiService.getPrs(repo).subscribe((prObjectArray) => {
              // set the variable here and use the built in getter, to get the current value
              let filteredObject = this.filteredObjectObservable.value;
              // do your stuff

              // at the very end of the subscribe callback, set the new value. This will also trigger all subscribers
              this.filteredObjectObservable.next(filteredObject);
        }
    }
    // subscribe to the BehaviorSubject (this could also be in the component's OnInit method or anywhere else).
    this.filteredObjectObservable.subscribe((value) => {
        // triggers each time the Subject's next() method is called
        this.repoCount = Object.keys(value).length;
    }
}

注意:代码未经测试:-)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-22
    • 2015-10-15
    • 2016-10-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多