我真的是角度上的新手,在可观察部分中更具体,所以我现在的问题是更多原因是因为我对订阅的使用不太了解。
让我解释一下。主要思想是创建一个带有对象的可观察列表(进入我的项目的service.ts),然后使用组件中的函数调用整个列表或该列表的特定对象作为可观察对象并进行订阅。列表中的每个对象都是遵循租户接口格式的租户。
在tenants.service.ts中,我创建了一个可观察的列表,并创建了一些函数来加载列表,从列表中租户并从列表中获取租户。
providedIn: 'root'
})
export class UpdateTenantsService {
/*** BehaviorSubject can receive and emit new Tenant lists ***/
private _tenants = new BehaviorSubject<Tenant[]>([]);
/*** Our api ***/
private base_url = 'http://localhost:5060';
/*** tenantsStore is where we store our list of tenants in memory ***/
private tenantsStore: { tenants: Tenant[] } = {tenants: []};
/*** To prevent the data from being altered outside the service we expose
* the BehaviorSubject through a public property and cast it to an Observable. ***/
readonly tenants = this._tenants.asObservable();
private tenantById: Observable<Tenant>;
private tenantByName: Observable<Tenant>;
constructor( private httpClient: HttpClient ) { }
loadAllTenants() {
this.httpClient.get<Tenant[]>(`${this.base_url}/tenants`).subscribe(data => {
this.tenantsStore.tenants = data['result']['tenants'];
/*** Instead of these methods returning new values of our tenants list ,
* they update our internal tenantsList. We make a copy using
* Object.assign() so we pass back a new copy of tenants and
* don’t accidentally pass a reference to the original tenantsList.***/
this._tenants.next(Object.assign({}, this.tenantsStore).tenants);
}, error => console.log('Could not load tenants.'));
}
loadSingleTenant(id: string) {
this.httpClient.get<Tenant[]>(`${this.base_url}/tenants/${id}`).subscribe(data => {
let notFound = true;
this.tenantsStore.tenants.forEach((tenant, index) => {
if (tenant.id === data['result']['tenants'].id) {
this.tenantsStore.tenants[index] = data['result']['tenants'];
notFound = false;
}
});
if (notFound) {
this.tenantsStore.tenants.push(data['result']['tenants']);
}
this._tenants.next(Object.assign({}, this.tenantsStore).tenants);
}, error => console.log('Could not load tenant.'));
}
getTenantById(id: string): Observable<Tenant> {
/***map is a RxJS pipeable operator. map applies a given function
* to each element emitted by the source Observable
* and emits the resulting values as an Observable . ***/
return this.tenants.pipe(
map(tenant => tenant.find(item => item.id === id ))
);
}
}
在我的tenant.component.ts中,我在调用tenantService.loadAllTenants之后创建了一些函数:subscription,update,getTenantById,稍后将通过html按钮使用,将所有租户加载到可观察的列表this.tenants
中。
tenants: Observable<Tenant[]>;
tenant: Observable<Tenant>;
id = '5d2f47a29864c29eab5996d5';
constructor(
private tenantsService: UpdateTenantsService
) { }
ngOnInit() {
/*Load all tenants*/
this.tenants = this.tenantsService.tenants;
this.tenantsService.loadAllTenants();
this.tenants.subscribe(tenants => {
console.log('tenants loaded');
console.log(tenants.length);
});
}
subscribe() {
this.tenantsService.getTenantById(this.id).subscribe(data => {
console.log('John loaded');
console.log(data.id);
console.log('---------');
});
}
update(id: string) {
this.tenantsService.loadSingleTenant(id);
}
getTenantById(id) {
this.tenantsService.getTenantById(id).subscribe(data => {
console.log('tenant loaded');
console.log(data.id);
console.log('---------');
});
}
}
tenant.html
<div class="container">
<button class="button" (click)="subscribe()">Subscribe </button>
<br>
<br>
<button class="button" (click)="update('mike_id')">Update ('id')</button>
<br>
<br>
<button class="button" (click)="getTenantById('john_id')">GET Tenant ('id')</button>
</div>
一切正常,但是...。问题是,当我调用订阅功能时,它将在控制台中打印``约翰已加载''(这意味着它确实已将订阅更正为可观察的租户)。之后,如果我选择单击更新功能,则在控制台中将会再次打印“ John loading” ...这意味着它再次进行了订阅,而无需我单击订阅按钮...如果我再次订阅john,则会出现第二个“ john loading”日志,并且它将保持保持在那里...就像程序一次订阅,在其中运行代码,永不退出订阅]
我需要退订吗?我真的不知道...
对不起,很长的帖子,在此先谢谢你!
[尝试将您的自定义方法名称更改为保留的方法名称以外的名称,例如subscribe()
。