Angular Material2 md-select dropdown appears at bo

2020-04-08 11:39发布

问题:

I'm currently using Angular Material2 in an Angular 2.4.0 application (using @angular/material: 2.0.0-beta.1). For some reason, the md-select dropdown, instead of appearing over the initial value or placeholder or arrow to select the dropdown, as demonstrated in these examples from the material docs, appears all the way at the bottom of the page. To the point that if the md-select dropdown is at the top right of the page (the component I am attempting to place mine in is at the top right of the page) when you click the arrow to view the dropdown options it will scroll you to the bottom of the page where they will be displayed. They will also be the full width of the page rather than the width of the dropdown.

Here is my component (at least the relevant bits - this app is fairly large + I commented out or removed as much code not relating to the dropdown (and removed everything in the view other than the dropdown to both narrow down the issue for myself as well as make it easier for anyone reading this to see the issue)):

import { Component, EventEmitter, Input, OnInit } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';

@Component({
  moduleId: module.id,
  selector: 'my-component',
  templateUrl: 'my-component.component.html',
  styleUrls: ['my-component.component.css'],
  providers: [FormBuilder]
})

export class MyComponent implements OnInit {
  @Input() page: Page;
  canvasBackgroundColors: string[] = ['White', 'Pink', 'Black'];
  draftModule: FormGroup;

  // --- Component Constructor ---

  constructor(private formBuilder: FormBuilder){}

  // --- Angular LifeCycle Hooks ---

  ngOnInit() {
    this.formBuilderInit();
  }

  // --- UI Delegates ---
  public onSave() {
   debugger;
  }

  // --- Private Helpers ---

  private formBuilderInit() {
    this.draftModule = this.formBuilder.group({
      canvasBackgroundColor: this.page.canvasBackgroundColor,
    });

    this.draftModule.valueChanges.subscribe(draftMod => {
      console.log('Test Module', draftMod);
    })
  }
}

The associated NgModule has the MaterialModule imported appropriately. Here is the entire view (haml):

%form{'[formGroup]' => 'draftModule', '(ngSubmit)' => 'onSave()'}

  %md-select{'formControlName' => 'canvasBackgroundColor'}
    %md-option{'*ngFor' => 'let color of canvasBackgroundColors', :value => '{{color}}'}
      {{color}}

  %button{:type => 'submit'}
    Save

Currently all the CSS for the entire app has been commented out so I know it's not something in there affecting the dropdown. The dropdown works perfectly and updates properly with form builder, its just that when you click the dropdown error the options suddenly show up all the way at the bottom of the page and are as wide as the page. Once you select an option you get scrolled back up to where your dropdown box is. I have searched everywhere and can't seem to find anyone else having this problem or a fix for it. The closest I came was one person mentioning in this github issue that they had this problem but they fixed it by adding theming. I tried this and adding theming did not make a difference in the way the dropdown worked.

For further clarification, when I inspect the dropdown options that appear at the bottom of the page I noticed that they appear not just outside of the component's template that md-select is in, but outside of the angular app entirely. The html shown in the inspector looks something like the following code (simplified of course to remove all the components that are not relevant to this issue). Note: my-app is the selector for the app component and cdk-overlay-container includes the md-select-panel and md-select-content and the dropdown options):

 <html>
   <head></head>
   <body id="body" class>
     <my-app>
       <my-component>
         <md-select></md-select>
       </my-component>
     </my-app>
     <div class="cdk-overlay-container"></div>
   </body>
</html>

Any advice would be appreciated!

回答1:

I had the same problem. I resolved it by importing the material theme:

@import '~@angular/material/core/theming/prebuilt/[one-of-the-themes].css';

in my main styleseet.



回答2:

If you are installing angular material to your angular cli project then your themes would be in node_modules/@angular/material/prebuilt-themes/

so import link would be something like shown below

@import "~@angular/material/prebuilt-themes/deeppurple-amber.css"

We should add the above line to our angular-cli application's styles.css file. Here deeppurple-amber.css is one of the prebuilt theme angular material is offering us. Most of the built-in components like md-select won't be working as expected if this import has not done properly.

Happy Coding :)



回答3:

I had the same problem but with the datepicker control. It was not popping up below the text box, but at the bottom of the page.

I tried what the other answer recommended and importing a theme into the styles.css file:

@import '~@angular/material/prebuilt-themes/deeppurple-amber.css';

and that didn't work for me by itself, but it was a step in the right direction.

But I also needed to make a couple changes to the app.module.ts file:

Add this to the imports:

import {OverlayContainer} from '@angular/material';

And change the app module class declaration:

export class AppModule {
constructor(overlayContainer: OverlayContainer) {
    overlayContainer.themeClass = 'unicorn-dark-theme';
}

You can find more info on this here:

https://material.angular.io/guide/theming

After doing all that, the date picker started working for me and not popping up at the bottom of the page when clicked.