Skip to content

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

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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions