我正在开发一个应用程序,我从私有git企业服务器中提取数据。我有一个字符串数组供repos检查,我将这些数据与一些来自本地JSON文件的数据结合起来给我一个像这样的结构:
{
repo1: {},
repo2: {},
repo3: {}
}
对象的回归与我期望的完全一样。问题是当我想得到一个计数。通常在JS中我使用Object.keys,但是当我这样做时返回一个空数组。我通过创建一个本地数组并将名称推入其中来暂时解决这个问题,因此我可以使用ngFor进行迭代。我挖的越多,它的意义就越小。我可以在对象文字上使用Object.keys,或者在没有问题的情况下使用我的预定义对象。问题是当我尝试在这个返回的对象上使用它时。我正在运行代码以获取ngOnInit()中的对象。当我在console.log中时它返回的对象完全符合预期,但如果我将日志更改为Object.keys(object),则返回空白。我想也许这是一个时间问题,所以我把这个函数包装在一个承诺中,然后将它链接起来。然后关闭它。同样,promise返回的对象看起来是正确的,但是我不能在它上面使用Object.keys。我也试过返回Object.keys(对象)而不是函数中的对象,但它仍然是空白的。
我有什么遗失的吗?是否有更多的角色'处理这个的方法?我已经使用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进行重构的原因。
答案 0 :(得分:0)
返回不会在订阅者上等待,因此filteredObject
为空。你应该让filteredObject
成为一个Observable(或者更确切地说是一个Subject)并订阅它。这部分代码在方法调用上按顺序执行:
const filteredObject = {};
const filteredArray = [];
tabArray.forEach((repo) => {
this.gitApiService.getPrs(repo).subscribe();
}
return Object.keys(filteredObject);
当subscribe()
触发返回的observable中的getPrs()
时,我会执行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;
}
}
注意:代码未经测试: - )