rxjs Error 抱怨类型不兼容
rxjs Error complaining about incompatible types
继续
自从在 SO 中接受一些指导以来,我已经阅读了相当多的书。我现在要解决 TS 抱怨不兼容类型的问题。我没有看到我的错误。
注意:我尝试开发代码,以便源与源之间的最大数量相同。一种技术是调用 'main' TYPE 'item'(在这种情况下......主要项目类型是 ProjRev)。
所以在这里,任何对 'item' 的引用都将指向 ProjRev 对象(当然 ProjectSvc.GetItemById 除外)
这似乎在最后一个 SO 中引起了混乱,我想我至少会澄清一下......
import { Component, OnInit, ElementRef, ViewChild } from '@angular/core';
import { Location } from '@angular/common';
import { ChangeDetectorRef } from '@angular/core';
import { Observable,forkJoin, combineLatest } from 'rxjs';
import { distinctUntilKeyChanged, pluck
, switchMap ,tap} from 'rxjs/operators';
import { ActivatedRoute } from '@angular/router';
import { Project } from '../project';
import { ProjectRev} from '../project-rev';
import { ProjectService } from '../services/project.service';
import { ProjectRevService } from '../services/project-rev.service';
interface VM{
projectRev : ProjectRev;
project : Project;
}
@Component({
selector: 'app-project-rev-detail',
templateUrl: './project-rev-detail.component.html',
styleUrls: ['./project-rev-detail.component.css']
})
export class ProjectRevDetailComponent implements OnInit {
private projectRevId$ : Observable<string>;
private myItem$ : Observable<ProjectRev>;
private myProject$ : Observable<Project>;
public vm$ : Observable<VM> ;
constructor( private projrevSvc : ProjectRevService
, private projectSvc : ProjectService
,private location: Location
,private activatedRoute: ActivatedRoute
) {
}
ngOnInit(): void {
this.projectRevId$ = this.activatedRoute.params.pipe(
pluck('id')
,tap( id => { console.log('pRevId',id);})
);
this.myItem$ = this.projectRevId$.pipe(
tap( item => { console.log('inside projrev pipe',item);})
, switchMap( (itemId : string) => this.projrevSvc.getItemById( itemId ))
, tap( item => console.log('rev retrieved',item))
);
this.myProject$ = this.myItem$.pipe(
tap( (prev : ProjectRev) =>{ console.log('inside getProj pipe');})
,distinctUntilKeyChanged('ProjectId')
,switchMap((item) => this.projectSvc.getItemById(item.ProjectId))
, tap( item => console.log('proj retrieved',item))
);
this.vm$ = combineLatest(
this.myItem$,
this.myProject$
).subscribe(([ projRev , project]) => {
this.myItem$ =projRev;
this.myProject$ = project;
});
错误信息是
ERROR in src/app/projects/project-rev-detail/project-rev-detail.component.ts(76,5): error TS2740: Type 'Subscription' is missing the following properties from type 'Observable<VM>': _isScalar, source, operator, lift, and 114 more.
src/app/projects/project-rev-detail/project-rev-detail.component.ts(81,9): error TS2740: Type 'ProjectRev' is missing the following properties from type 'Observable<ProjectRev>': _isScalar, source, operator, lift, and 114 more.
src/app/projects/project-rev-detail/project-rev-detail.component.ts(82,9): error TS2740: Type 'Project' is missing the following properties from type 'Observable<Project>': _isScalar, source, operator, lift, and 114 more.
正在调用的服务函数在这里...
正如我的日志列表所证明的那样,这是有效的
getItemById(id: string): Observable< ProjectRev> {
console.log('inside proj rev getItemByid..');
const url = `${this.serviceUrl}/${id}`;
return this.http.get< ProjectRev>(url, httpOptions)
.pipe(
catchError(err =>
this.handleError(`getItemById=${id}`, err))
);
}
我试过将 VM 接口更改为可观察的而不是可观察的。
我已经完成了更改接口和 combineLatest 参数签名的所有排列
我很确定这就是我的问题所在。
问题:当我在 ngOnit() 中初始化可观察对象时没有订阅;我从 SO answer 中获取了这个模式。应该有订阅吗?
我之前犯了不订阅的错误……这里不需要吗?
VM 模式不是必需的。它是在 SO 答案中提出的。我确实看到了将整个 UI 包装在 1 ngIf 中的优势...但前提是我可以让它工作。我可以 google 为这种模式命名吗?谁有好的例子?
考虑一下:
public count : number;
initCount(){
this.count = "Hello!";
}
预期错误:Type 'string' is not assignable to type 'number'
那是因为我先说count是一个数字,然后给它赋了一个字符串。如何解决这个问题取决于意图。考虑到 count 的命名方式,once 可能会认为给它分配一个字符串是错误的。
关于你的代码:)
public vm$: Observable<VM>;
ngOnInit(){
this.vm$ = someObservable.subscribe(someLambda);
}
在这里,您正在尝试将订阅分配给一个可观察对象。它与上面的错误大致相同,但 TypeScript 会尝试进行 duck-typing(查看对象属性并查看它们是否匹配)。订阅和可观察对象不重叠。
这就是您的错误消息告诉您的内容。
如何解决这个问题?最好的方式/惯用方式很难从您在这里写的内容中看出,但这是类型可能再次对齐的一种方式。
this.vm$ = combineLatest(
this.myItem$,
this.myProject$
).pipe(
map(([projectRev, project]) => ({
projectRev,
project
}))
);
继续
自从在 SO 中接受一些指导以来,我已经阅读了相当多的书。我现在要解决 TS 抱怨不兼容类型的问题。我没有看到我的错误。
注意:我尝试开发代码,以便源与源之间的最大数量相同。一种技术是调用 'main' TYPE 'item'(在这种情况下......主要项目类型是 ProjRev)。
所以在这里,任何对 'item' 的引用都将指向 ProjRev 对象(当然 ProjectSvc.GetItemById 除外)
这似乎在最后一个 SO 中引起了混乱,我想我至少会澄清一下......
import { Component, OnInit, ElementRef, ViewChild } from '@angular/core';
import { Location } from '@angular/common';
import { ChangeDetectorRef } from '@angular/core';
import { Observable,forkJoin, combineLatest } from 'rxjs';
import { distinctUntilKeyChanged, pluck
, switchMap ,tap} from 'rxjs/operators';
import { ActivatedRoute } from '@angular/router';
import { Project } from '../project';
import { ProjectRev} from '../project-rev';
import { ProjectService } from '../services/project.service';
import { ProjectRevService } from '../services/project-rev.service';
interface VM{
projectRev : ProjectRev;
project : Project;
}
@Component({
selector: 'app-project-rev-detail',
templateUrl: './project-rev-detail.component.html',
styleUrls: ['./project-rev-detail.component.css']
})
export class ProjectRevDetailComponent implements OnInit {
private projectRevId$ : Observable<string>;
private myItem$ : Observable<ProjectRev>;
private myProject$ : Observable<Project>;
public vm$ : Observable<VM> ;
constructor( private projrevSvc : ProjectRevService
, private projectSvc : ProjectService
,private location: Location
,private activatedRoute: ActivatedRoute
) {
}
ngOnInit(): void {
this.projectRevId$ = this.activatedRoute.params.pipe(
pluck('id')
,tap( id => { console.log('pRevId',id);})
);
this.myItem$ = this.projectRevId$.pipe(
tap( item => { console.log('inside projrev pipe',item);})
, switchMap( (itemId : string) => this.projrevSvc.getItemById( itemId ))
, tap( item => console.log('rev retrieved',item))
);
this.myProject$ = this.myItem$.pipe(
tap( (prev : ProjectRev) =>{ console.log('inside getProj pipe');})
,distinctUntilKeyChanged('ProjectId')
,switchMap((item) => this.projectSvc.getItemById(item.ProjectId))
, tap( item => console.log('proj retrieved',item))
);
this.vm$ = combineLatest(
this.myItem$,
this.myProject$
).subscribe(([ projRev , project]) => {
this.myItem$ =projRev;
this.myProject$ = project;
});
错误信息是
ERROR in src/app/projects/project-rev-detail/project-rev-detail.component.ts(76,5): error TS2740: Type 'Subscription' is missing the following properties from type 'Observable<VM>': _isScalar, source, operator, lift, and 114 more.
src/app/projects/project-rev-detail/project-rev-detail.component.ts(81,9): error TS2740: Type 'ProjectRev' is missing the following properties from type 'Observable<ProjectRev>': _isScalar, source, operator, lift, and 114 more.
src/app/projects/project-rev-detail/project-rev-detail.component.ts(82,9): error TS2740: Type 'Project' is missing the following properties from type 'Observable<Project>': _isScalar, source, operator, lift, and 114 more.
正在调用的服务函数在这里... 正如我的日志列表所证明的那样,这是有效的
getItemById(id: string): Observable< ProjectRev> {
console.log('inside proj rev getItemByid..');
const url = `${this.serviceUrl}/${id}`;
return this.http.get< ProjectRev>(url, httpOptions)
.pipe(
catchError(err =>
this.handleError(`getItemById=${id}`, err))
);
}
我试过将 VM 接口更改为可观察的而不是可观察的。 我已经完成了更改接口和 combineLatest 参数签名的所有排列 我很确定这就是我的问题所在。
问题:当我在 ngOnit() 中初始化可观察对象时没有订阅;我从 SO answer 中获取了这个模式。应该有订阅吗? 我之前犯了不订阅的错误……这里不需要吗?
VM 模式不是必需的。它是在 SO 答案中提出的。我确实看到了将整个 UI 包装在 1 ngIf 中的优势...但前提是我可以让它工作。我可以 google 为这种模式命名吗?谁有好的例子?
考虑一下:
public count : number;
initCount(){
this.count = "Hello!";
}
预期错误:Type 'string' is not assignable to type 'number'
那是因为我先说count是一个数字,然后给它赋了一个字符串。如何解决这个问题取决于意图。考虑到 count 的命名方式,once 可能会认为给它分配一个字符串是错误的。
关于你的代码:)
public vm$: Observable<VM>;
ngOnInit(){
this.vm$ = someObservable.subscribe(someLambda);
}
在这里,您正在尝试将订阅分配给一个可观察对象。它与上面的错误大致相同,但 TypeScript 会尝试进行 duck-typing(查看对象属性并查看它们是否匹配)。订阅和可观察对象不重叠。
这就是您的错误消息告诉您的内容。
如何解决这个问题?最好的方式/惯用方式很难从您在这里写的内容中看出,但这是类型可能再次对齐的一种方式。
this.vm$ = combineLatest(
this.myItem$,
this.myProject$
).pipe(
map(([projectRev, project]) => ({
projectRev,
project
}))
);