Skip to content

Feature: Allow user to provide bindings for a ComponentPortal #717

@shlomiassaf

Description

@shlomiassaf

Bug, feature request, or proposal: feature

What is the expected behavior?

A user can provide optional ResolvedReflectiveProvider[] to the constructor of ComponentPortal, this is a good way to provide data for dialogs.

What is the current behavior?

The component type in ComponentPortal use the injector of the ViewContainerRef.
Dialog must use a service to get data from the application.

Before creating the component in DomPortalHost create a child injector with the bindings:

  /** DomPortalHost **/
  /** Attach the given ComponentPortal to DOM element using the ComponentResolver. */
  attachComponentPortal(portal: ComponentPortal): Promise<ComponentRef<any>> {
    if (portal.viewContainerRef == null) {
      throw new MdComponentPortalAttachedToDomWithoutOriginError();
    }

    return this._componentResolver.resolveComponent(portal.component).then(componentFactory => {
      const childInjector = ReflectiveInjector
        .fromResolvedProviders(portal.bindings,  portal.viewContainerRef.parentInjector);

      let ref = portal.viewContainerRef.createComponent(
          componentFactory, portal.viewContainerRef.length, childInjector);

      let hostView = <EmbeddedViewRef<any>> ref.hostView;
      this._hostDomElement.appendChild(hostView.rootNodes[0]);
      this.setDisposeFn(() => ref.destroy());
      return ref;
    });
  }


/** ComponentPortal **/
/**
 * A `ComponentPortal` is a portal that instantiates some Component upon attachment.
 */
export class ComponentPortal extends Portal<ComponentRef<any>> {
  /** The type of the component that will be instantiated for attachment. */
  public component: Type;

  public bindings: ResolvedReflectiveProvider[];

  /**
   * [Optional] Where the attached component should live in Angular's *logical* component tree.
   * This is different from where the component *renders*, which is determined by the PortalHost.
   * The origin necessary when the host is outside of the Angular application context.
   */
  public viewContainerRef: ViewContainerRef;

  constructor(component: Type, viewContainerRef: ViewContainerRef = null,
              bindings: ResolvedReflectiveProvider[] = null) {
    super();
    this.component = component;
    this.viewContainerRef = viewContainerRef;
    this.bindings = Array.isArray(bindings) ? bindings : [];
  }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions