动态组件加载-将组件作为变量获取

问题描述

我正在Angular中实现一个相对复杂的component loader,并且我想从rxjs存储中动态获取组件实例。

loadEditAreaComponent(component: any,componentInstanceData?: {}){
    const componentFactory = this.cfr.resolveComponentFactory(component);
    const viewContainerRef = this.editAreaHost.viewContainerRef;
    const componentRef = viewContainerRef.createComponent(componentFactory);
    Object.keys(componentInstanceData).forEach(key => {
      componentRef.instance[key] = componentInstanceData[key];
})

有效。但是,我觉得any在这里有点草率。我似乎找不到正确的类型。

resolveComponentFactory的签名是 (method) ComponentFactoryResolver.resolveComponentFactory<unkNown>(component: Type<unkNown>): ComponentFactory<unkNown>

当我说component: Type时,我得到: Argument of type 'Type' is not assignable to parameter of type 'Type<unkNown>'.

当我说component: Type<unkNown>Type<any>时,我得到: Type 'Type' is not generic.

不胜感激,也希望获得一些有关Typescript约束的背景知识,我可能无法理解。

谢谢!

解决方法

resolveComponentFactory方法的签名如下:

export const PlacementsForm = () => {
  const [placementData,setPlacementData] = useState([
    { key: 1,name: 'Long side panel',value: 10 },{ key: 2,name: 'Custom wrap',value: 0 },{ key: 3,name: 'Seatback',{ key: 4,name: 'Full wrap',value: 20 },{ key: 5,name: 'Driver’s cabin',{ key: 6,name: 'Stop side panel',{ key: 7,name: 'Max Parade',value: 60 },{ key: 8,name: 'Parade',{ key: 9,name: 'Full rear',value: 70 },{ key: 10,name: 'Rear panel',]);

  const handleSliderChange = (event) => {
    setPlacementData({
      ...placementData,[event.target.name]: event.target.value,});
  };

  const handleInputChange = (event,idx) => {
    const usedSlider = event.target;
    setPlacementData(() => placementData.map((item,i) => usedSlider.value));
  };

  //   const handleInputChange = (event) => {
  //     setPlacementData(
  //       event.target.value === '' ? '' : Number(event.target.value)
  //     );
  //   };

  //   const handleSliderChange = (name) => (event) => {
  //     // placementData[index] = event.target.value;
  //     // setPlacementData([...placementData]);
  //     setPlacementData({ [name]: event.target.value });
  //   };

  //   const handleInputChange = (name) => (event,value) => {
  //     // placementData[index].value = event.target.value;
  //     // setPlacementData([...placementData]);
  //     setPlacementData({ [name]: value });
  //   };

  console.log('placementData',placementData);

  return (
    <SliderContainer>
      <Grid>
        <Row>
          {placementData.map((option) => (
            <Col xs={6} md={6} key={option.name}>
              <SliderTitle>{option.name}</SliderTitle>
              <SliderItem key={option.key}>
                <MatGrid item xs>
                  <Slider
                    value={typeof option.value === 'number' ? option.value : 0}
                    onChange={handleSliderChange}
                    aria-labelledby="input-slider"
                    valueLabelDisplay="auto"
                  />
                </MatGrid>
                <MatGrid item>
                  <Input
                    name={option.name}
                    style={{ width: '50px',paddingLeft: 15 }}
                    value={option.value}
                    margin="dense"
                    onChange={handleInputChange}
                    // onBlur={handleBlur}
                    inputProps={{
                      step: 10,min: 0,max: 100,type: 'number','aria-labelledby': 'input-slider',}}
                  />
                </MatGrid>
              </SliderItem>
            </Col>
          ))}
        </Row>
      </Grid>
    </SliderContainer>
  );
};

您应该使用相同的类型:

abstract resolveComponentFactory<T>(component: Type<T>): ComponentFactory<T>;