Как создать компоненты более высокого порядка в Angular 2

#angular

#angular

Вопрос:

Компоненты более высокого порядка (HOC) — это шаблон, распространенный среди сообщества React. Посмотрите эту статью, если вы не знаете, что такое HOC

Имеют ли они смысл в Angular 2? Как создать HOC? Есть примеры?

Комментарии:

1. Может быть, это может помочь: angular.io/docs/ts/latest/cookbook/dynamic-form.html , имею в виду.эксперт/2016/05/14/ угловой-2-контейнерный-компонент

2. Вопрос в его текущем состоянии требует хорошего понимания как React, так и Angular 2. Объяснение того, что именно вы хотите сделать, без использования специального термина, увеличит шансы получить качественный ответ.

Ответ №1:

Используйте NgComponentOutlet

Простой случай

 @Component({selector: 'hello-world', template: 'Hello World!'})
class HelloWorld {
}

@Component({
  selector: 'ng-component-outlet-simple-example',
  template: `<ng-container *ngComponentOutlet="myComponent"></ng-container>`
})
class NgTemplateOutletSimpleExample {
  // This field is necessary to expose HelloWorld to the template.
  myComponent= HelloWorld;
}
 

Дополнительные примеры, включая предоставление инжектора и содержимого, доступны в официальной документации

Ответ №2:

Меня также очень интересует что-то похожее на HOC (перекомпонировать, как в Angular 2). Недавно я пытался создать аналог mapToProps HOC’ Recompose для Angular — mapToInputs, используя директиву Angular structural . Я ищу лучший подход.

   @Component({
    selector: 'user-list',
    template: `
       <h2>{{status}} users</h2> 
       <div *ngFor="let item of data">{{item}}</div>
    `
  })
  export class UserList {
    @Input() data: Array<any>;
    @Input() status: string;
  }

  @Directive({selector: '[mapInputs]'})
  export class MapInputs {
    component;

    @Input() set mapInputsComponent(component) {
     this.component = component;
    }

    @Input() set mapInputs(fn) {
      this.vc.clear();
      let factory = this.componentFactoryResolver.resolveComponentFactory(this.component);
      let componetRef =  this.vc.createComponent(factory);

      let inputs = fn();
      console.log(inputs);
      Object.entries(inputs).forEach(([key, value]) => {
        componetRef.instance[key] = value;
      });
    }

    constructor(private vc: ViewContainerRef, 
          private componentFactoryResolver: ComponentFactoryResolver) {
    }
  }

  @Component({
    selector: 'my-app',
    template: `
      <div>
        <button (click)="doubledata()">Doubel Data</button>
        <div *mapInputs="filterBy.bind(null, {data:data, status:'active'}); component: component"></div>
        <div *mapInputs="filterBy.bind(null, {data:data, status:'passive'}); component: component"></div>
        <div *mapInputs="filterBy.bind(null,  {data:data, status:'blocked'}); component: component"></div>
      </div>
    `,
  })
  export class App {
    name: string;
    component = UserList;
    data = ['active', 'active', 'passive', 'blocked', 'blocked'];
    filterBy = (context) => {
       return {
          status: context.status,
          data: context.data.filter(el => el ===  context.status);
       };
    }

    doubledata(){
      this.data = this.data.concat(this.data);
    }

    constructor() {
      this.name = `Angular! v${VERSION.full}`
    }
  }
 

Комментарии:

1. Это выглядит как достойный подход. Похоже, что Angular не позволяет вам «естественно» это делать… Используете ли вы этот подход для себя, Джулия?

2. вот два типа HOC. Proxy props HOC можно создать с помощью angular, но инверсии наследования — я понятия не имею, как это сделать с angular с помощью AOT. Мне просто очень нравится идея HOC в react и не хватает ее в angular.

3. @JuliaPassynkova это вполне возможно с IVY medium.com/angular-in-depth /…