You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Angular组件中读取所有@Input装饰器修饰的成员?

How to Read All @Input() Properties in an Angular Component

Hey there! I’ve struggled with this exact problem before—trying to use reflect or reflect-metadata directly just doesn’t work because Angular handles component metadata its own way. Let me break down two reliable approaches to get those @Input() properties.

Why Direct reflect-metadata Fails

Angular doesn’t store @Input() metadata in the standard reflect-metadata keys you might expect. Instead, during compilation, it generates internal metadata structures for components, which is where we need to look.


Approach 1: Use Angular’s Internal Component Metadata (Quick & Dirty)

Angular compiles every component with an internal ɵcmp property that holds all the component’s metadata, including inputs. This is straightforward, just note that it’s an internal API (so it might change between Angular versions, but it’s been stable for a while).

Example Code

First, here’s a sample component with inputs:

import { Component, Input } from '@angular/core';

@Component({
  selector: 'app-user-profile',
  template: '<h1>{{username}}</h1><p>Age: {{userAge}}</p>'
})
export class UserProfileComponent {
  @Input() username: string = '';
  @Input('userAge') age: number = 0; // Using a custom binding name
}

Now extract the inputs:

import { UserProfileComponent } from './user-profile.component';

// Access the internal component metadata
const componentMeta = UserProfileComponent['ɵcmp'];

// Extract input data: inputs is an array of [bindingName, propertyName] pairs
const inputPairs = componentMeta.inputs;

// Convert to a more usable map
const inputMap = new Map(inputPairs);

// Log the results
console.log('Component Inputs:');
inputMap.forEach((propertyName, bindingName) => {
  console.log(`Binding Name (template): ${bindingName}, Component Property: ${propertyName}`);
});

Output

Component Inputs:
Binding Name (template): username, Component Property: username
Binding Name (template): userAge, Component Property: age

Approach 2: Use Angular’s Public API (Stable for Production)

If you want a production-safe method that uses Angular’s public APIs, use ComponentFactoryResolver to resolve the component factory, which exposes input metadata.

Step 1: Create an Extractor Service

import { Injectable, ComponentFactoryResolver, ComponentFactory } from '@angular/core';

@Injectable({ providedIn: 'root' })
export class InputMetadataExtractor {
  constructor(private cfr: ComponentFactoryResolver) {}

  getComponentInputs(componentClass: any): Array<{ bindingName: string; propertyName: string }> {
    const factory: ComponentFactory<any> = this.cfr.resolveComponentFactory(componentClass);
    // Map the factory's input metadata to a friendly format
    return factory.inputs.map(input => ({
      bindingName: input.propName, // The name used in templates
      propertyName: input.templateName // The actual property name in the component class
    }));
  }
}

Step 2: Use the Service in a Component/Service

import { Component, OnInit } from '@angular/core';
import { UserProfileComponent } from './user-profile.component';
import { InputMetadataExtractor } from './input-metadata-extractor.service';

@Component({
  selector: 'app-input-demo',
  template: '<div></div>'
})
export class InputDemoComponent implements OnInit {
  constructor(private inputExtractor: InputMetadataExtractor) {}

  ngOnInit(): void {
    const userProfileInputs = this.inputExtractor.getComponentInputs(UserProfileComponent);
    console.log('Stable API Inputs:', userProfileInputs);
  }
}

Output

Stable API Inputs: [
  { bindingName: "username", propertyName: "username" },
  { bindingName: "userAge", propertyName: "age" }
]

Key Notes

  • Internal API Caveat: The ɵcmp property is not officially documented, so while it works for most Angular versions (v9+), be cautious when upgrading major versions.
  • Public API Benefit: The ComponentFactoryResolver approach is fully supported and won’t break with Angular updates, making it ideal for production apps.
  • Why Reflect Failed: Angular doesn’t expose @Input() metadata via standard reflect-metadata methods—it compiles metadata into its own internal structures, which is why we need these Angular-specific approaches.

内容的提问来源于stack exchange,提问作者Yang Rui

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:27:46