我现在真的很困惑,因为我得到了ERROR TypeError: "_this.device.addKeysToObj is not a function"
。但是我实现了这个函数,所以我不知道问题出在哪里,也不知道为什么它不能调用。我已经尝试了Firefox和Chrome的代码,都通过相同的错误。
错误在this.device.addKeysToObj(this.result.results[0]);
行
以下是我的班级:
export class Device {
id: number;
deviceID: string;
name: string;
location: string;
deviceType: string;
subType: string;
valueNamingMap: Object;
addKeysToObj(deviceValues: object): void {
for (let key of Object.keys(deviceValues).map((key) => { return key })) {
if (!this.valueNamingMap.hasOwnProperty(key)) {
this.valueNamingMap[key] = '';
}
}
console.log(this, deviceValues);
}
}
这就是召唤
export class BatterieSensorComponent implements OnInit {
@Input() device: Device;
public result: Page<Value> = new Page<Value>();
//[..]
ngOnInit() {
this.valueService.list('', this.device).subscribe(
res => {
console.log(this.device); // NEW edit 1
this.result = res;
if (this.result.count > 0)
{
this.device.addKeysToObj(this.result.results[0]);
}
}
)
}
}
编辑1
日志记录this.device
参见上面代码中的注解:
{
deviceID: "000000001"
deviceType: "sensor"
id: 5
location: "-"
name: "Batteries"
subType: "sensor"
valueNamingMap:
Object { v0: "vehicle battery", v1: "Living area battery" }
<prototype>: Object { … }
}
编辑2
设备的一部分。服务代码:
list(url?: string, deviceType?: string, subType?: string): Observable<Page<Device>> {
if(!url) url = `${this.url}/devices/`;
if(deviceType) url+= '?deviceType=' + deviceType;
if(subType) url+= '&subType=' + subType;
return this.httpClient.get<Page<Device>>(url, { headers: this.headers })
.pipe(
catchError(this.handleError('LIST devices', new Page<Device>()))
);
}
父组件中的调用:
ngOnInit() {
this.deviceService.list('', 'sensor', ).subscribe(
res => {
this.devices = res.results;
}
)
}
模板:
<div class="mdl-grid">
<div class="mdl-cell mdl-cell--6-col mdl-cell--6-col-tablet" *ngFor="let device of devices">
<app-batterie-sensor [device]="device"></app-batterie-sensor>
</div>
</div>
5条答案
按热度按时间idv4meu81#
原始答案
这是Typescript的一个常见问题,你说
device
是Device
类型,但它不是。它具有与Device
相同的所有属性,但由于它不是Device
,因此没有预期的方法。您需要确保为
Page
(可能是父组件的ngOnInit
)中的每个条目示例化Device
:我不知道
Page
的结构,但如果它是一个数组,请尝试以下操作。进一步说明
让我们尝试一个typescript示例,因为这种行为与Angular没有任何关系。我们将使用
localStorage
来表示来自外部源的数据,但这与HTTP的工作原理相同。很好用,太棒了。类型脚本接口是一个纯粹的编译时结构,与类不同,它在JavaScript中没有等价物-它只是一个开发人员提示。但这也意味着,如果你为一个外部值创建了一个接口,比如上面的
SimpleValue
,并且得到了 * 错误 *,那么编译器仍然会相信你知道你在说什么,它不可能在编译时验证这个。如何从外部源加载类?这有什么不同?如果我们以上面的例子为例,将
SimpleValue
更改为一个类,而不更改任何其他内容,那么它仍然可以工作。但还是有区别的。与接口不同的是,类被转译成它们的JavaScript等价物,换句话说,它们存在于编译点之后。在我们上面的例子中,这不会导致问题,所以让我们尝试一个确实导致问题的例子。加载的值具有我们预期的属性,但没有方法,哦哦!问题是当调用
new SimpleClass
时会创建方法。当我们创建valueToSave
时,我们确实示例化了这个类,但是后来我们把它变成了一个JSON字符串并把它发送到其他地方,而JSON没有方法的概念,所以信息丢失了。当我们在loadFromStorage
中加载数据时,我们并没有调用new SimpleClass
,我们只是相信调用者知道存储的类型是什么。我们该怎么处理这件事?让我们回到Angular,考虑一个常见的用例:dates. JSON没有Date类型,JavaScript有,那么我们如何从服务器中检索日期并将其作为日期工作呢?这是我喜欢用的一个模式。
也许有点冗长,但它是我用来处理来自扁平后端契约的丰富前端模型的最健壮和最灵活的模式。
qnyhuwrf2#
你可能在这里遇到了一个与公认答案不同的问题:如果你正在使用Angular的服务,忘记了
@Injectable
,使用Angular Ivy,你会得到一个像这样的运行时异常:正确的解决方案是将
@Injectable
也添加到实现中,例如:参见Angular 7 TypeError: service.x is not a function。
muk1a3rh3#
在我的案例中,我测试了两种对我有效的解决方案
将代码 Package 在***setTimeout***中
或
另一个解决方案是添加***条件***
v8wbuo2f4#
正如@UncleDave已经解释过的,您只是将具有相应名称的值Map到Typescript对象,但并没有使用它创建预期的类对象。我知道这很让人困惑。
Object.assign()
可以解决当前的问题,但如果你有嵌套对象,就不会了。然后,您还必须为每个嵌套对象执行Object.assign()
,如果您必须在代码库中的多个位置执行此操作,则会变得繁琐。我建议另一种选择:class-transformer通过这个,你可以用注解来标记你的嵌套字段,告诉编译器如何创建嵌套对象。这样,你只需要使用
plainToClass()
方法来Map你的顶层对象,所有的底层字段也会有正确的类型/对象。示例
假设我们有两个类:
第一种情况我们已经知道不起作用:
第二种情况使用
Object.assign()
:要使其发挥作用,我们必须做到以下几点:
第三种情况带类变压器:
首先修改父类,以便定义子Map:
然后你可以Map到父对象:
z2acfund5#
我在这篇文章中给出的答案帮助了我。我从YT的一个视频中得到的,基本上说你需要检查这个类的方法是否存在。https://stackoverflow.com/a/76186682/21161371