【问题标题】:Get and execute function from key: value pair Object in Angular 9从键获取并执行函数:Angular 9中的值对对象
【发布时间】:2020-08-03 09:39:26
【问题描述】:

我有一个简单的组件,它所做的只是呈现资源列表。这些资源是从我在这个组件中调用的服务中获取的。当调用该服务时,我会广播一条消息,让其他组件知道某个资源已添加到数据库中。我正在尝试在广播特定消息时执行特定功能。

// service/service-list/service-list.component.ts
import { Component, OnInit } from '@angular/core';
import { Service } from '../service.model'
import { HttpClient } from '@angular/common/http';
import { ServiceApi } from '../service.api';
import { MessagingService } from 'src/app/messaging.service';
import { ServiceFunctionMaps } from '../service.function.maps.model';
import { ServiceFunction } from '../service.function.model';

@Component({
  selector: 'app-service-list',
  templateUrl: './service-list.component.html',
  styleUrls: ['./service-list.component.css']
})
export class ServiceListComponent implements OnInit {

  allServices: Service[]
  functionMaps: ServiceFunctionMaps = {
    // serviceAdded: this.getAllServices
    serviceAdded: <ServiceFunction>this.getAllServices
  }

  constructor(private http: HttpClient, private api: ServiceApi, private msgService: MessagingService) {
    this.msgService.readMessage().subscribe(msg => {
      this.functionMaps[msg]()
      // The if statement works just fine
      // if (msg === 'serviceAdded') {
      //   this.getAllServices()
      // }
    })
    this.msgService.cleareMessage()
  }

  ngOnInit(): void {
    this.getAllServices()
  }

  private getAllServices() {
    this.api.fetchAllServices().subscribe(responseData => {
      this.allServices = responseData
    })
  }
}
// service/service-function.ts
export interface ServiceFunction {
  (params?: string): void
  // (params?: string): Function
  // (params?: string): () => void
}
// service/service-function-maps.model.ts
import { ServiceFunction } from './service-function.model';

export interface ServiceFunctionMaps {
  [key: string]: ServiceFunction
}

如您所见,我想根据广播的消息动态执行一个函数。现在代码可以编译,但我在控制台中遇到这样的错误......

core.js:6189 ERROR TypeError: this.functionMaps[msg] is not a function
// tsconfig.json
{
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "downlevelIteration": true,
    "experimentalDecorators": true,
    "module": "esnext",
    "moduleResolution": "node",
    "importHelpers": true,
    "target": "es2015",
    "lib": [
      "es2018",
      "dom"
    ],
    "resolveJsonModule": true
  },
  "angularCompilerOptions": {
    "fullTemplateTypeCheck": true,
    "strictInjectionParameters": true
  }
}

如何创建要动态执行的函数对象?

【问题讨论】:

  • 为什么使用接口作为函数的类型而不是 lambda 类型(如这里描述的typescriptlang.org/docs/handbook/…)?
  • 您能否详细说明为什么要从对象而不是组件/服务执行函数?
  • @RMo,当然。当发生某些事情时,我正在广播来自其他组件的消息,例如,在数据库中创建了一条新记录。在另一个组件中,我想根据广播的消息执行特定功能。我避免使用@Input()Output()
  • 您正在使用具有公共 observable 的服务,您的组件可以订阅该服务。您可以使用 switch(msg) case 'service added': this.doSomething(); break; 在成功时调用私有方法来检查结果。所以我仍然不太清楚你为什么要在这里使用地图。
  • 你是对的@RMo,我可以用switch 做到这一点,但你正在查看完整应用程序的一小部分。我不知道您是否知道从对象运行 func 比 switch 或 `if () {}` 更快。 jsperf.com/if-switch-lookup-table/10

标签: angular typeerror


【解决方案1】:

更新

两个修改解决了这个问题:

  1. bind(this)
  // I don't need the type interface
  functionMaps = {
    serviceAdded: this.getAllServices.bind(this)
  }
  1. if () {}。似乎在第一次加载组件时,它没有声明对象。
this.msgService.readMessage().subscribe(msg => {
  if(this.functionMaps[msg]){
    this.functionMaps[msg]();
  }
})

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多