我想答案将非常明显,但仍然回避了我。我对使用可观察对象是新手,现在我面临着从中分配值的问题。如果我将其(this._apps)定义为Observable并使用订阅从视图向服务进行查询,我就取得了成功(但是我的想法是令人费解的(映射内的三个层次只是为了返回数组的另一个Observable,然后另一个用于订阅前一个函数以分配变量的函数,以及另一个在视图中进行订阅以最终显示信息的函数),效率低下,最重要的是,我无法再次“正确”使用它。任务很简单。给定应用程序类
export class Application {
name: string;
baseUrl: string;
deprecated: boolean;
}
和服务(只是相关代码)
private _apps: Application[] = [];
constructor(private _http: HttpClient) {
this.getAllApplications().subscribe(apps => {
console.log('Apps subscriber');
this._apps = apps;
console.log('Apps subscriber Ends ' + apps);
},
err => {
console.log(err.status); // 401
console.log(err.error.error); // undefined
console.log(JSON.parse(err.error).error); // unauthorized
});
}
private getAllApplications() {
return this._http.get<Application[]>('http://development:4300/api/v1/apps');
}
从构造函数中触发了从WebAPI获取信息的函数,并且远程调用成功,但是如果我尝试从代码中的任何位置调用变量this._apps,则该变量为空数组。我无法确定订阅函数中参数“ apps”的类型,但是由于某种原因,无法分配它,给出的最佳答案是它是我尝试的一个函数(请参阅我的第一个更新)。当前,它在控制台“ [object Object]”中返回,但是apps [0]给出了undefined,因此它是一个空数组。
这是控制台输出,仅启动应用程序:
Angular在开发模式下运行。调用enableProdMode()以启用生产模式。 刷新的应用程序缓存调用http://development:4300/api/v1/atbc-apps 应用订阅者 Apps订阅者结束[对象对象]
我尝试过this solution的许多我忘记的事情(使用更现代的HttpClient代替以前使用的Http),那么我在做什么错呢?
更新1
我将构造函数更改为此:
constructor(private _http: HttpClient) {
this.getAllApplications().subscribe(apps => {
console.log('apps length ' + apps.length);
this._apps = apps; // Remember private _apps: Application[] = [];
console.log('Apps subscriber Ends ' + apps.toString);
},
err => {
console.log(err.status); // 401
console.log(err.error.error); // undefined
console.log(JSON.parse(err.error).error); // unauthorized
});
}
以及在其中调用的函数的声明:
private getAllApplications(): Observable<Application[]> {
// the exactly the same as before
}
现在我从控制台获得了这个信息:
应用程序长度未定义
Apps订户端
function () {
if (this instanceof Promise) {
return PROMISE_OBJECT_TO_STRING;
}
return originalObjectToString.apply(this, arguments);
}
那是我在说的功能。关于为什么即使没有错误(编译时也没有运行时)为什么返回对象不是真正的Application数组的任何想法?
答案 0 :(得分:0)
更改此行:
private _apps: Application[] = [];
收件人:
_apps: Application[] = [];
默认情况下将其公开。然后此行将看到它:
this._apps = apps;
答案 1 :(得分:0)
最后,我认为使用Observables是一种心态,并且我尝试构建一种缓存,因此,我能做到的唯一方法(让我知道是否有更好的方法)是使用视图填写缓存。我不能从服务本身做到这一点,因为从视图中调用函数是同步的,并且要填充数组是异步的。因此,我必须创建一个公共的setApplicationCache过程,该过程在从视图中调用该服务后将被填充,该过程将调用setApplicationCache(Application [])函数,其余的工作正常,因为它仅需要缓存来执行过滤和其他操作或使用它从其他页面开始,没有一次又一次地调用数据库。
这是第一个视图(主页)中的代码
ngOnInit() {
this._myService.getAllApplications().subscribe(arrObjApps => {
this._myService.setApplicationsCache(arrObjApps)
this.listApps = this._myService.getApplications(true);
});
该服务具有以下功能:
private _apps: Application[] = [];
getAllApplications(): Observable<Application[]> {
return this._http.get('http://development:4300/api/v1/atbc-apps').pipe(
map( (response: Response) => {
let results = response.json().data.map( app => {
return new Application(app.name, app.baseUrl, app.deprecated);
});
return results;
})
);
}
getApplication(appName: string): Application {
return this._apps.find(app => app.name == appName);
}
getApplications(onlyActives: boolean): Application[] {
if (onlyActives) {
return this._apps.filter(app => app.deprecated == false);
} else {
return this._apps;
}
}
正如我所说,解决方案应该很明显。再次需要使用可观察对象的异步思维方式。