如何在选择下显示选项(Angular material 7)? [英] How to show options under select (Angular material 7)?

查看:29
本文介绍了如何在选择下显示选项(Angular material 7)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在选择下显示选项(Angular material 7)?

类似于默认选择:

解决方案

正确"的答案是在 mat-select 上使用 disableOptionCentering,但即使这样也只能防止占位符被覆盖并且不模仿基本的本机选择.

强烈反对在 Angular 中对本机元素进行 DOM 操作,但不幸的是,这是我发现做这样的事情的唯一方法......

  • 希望有人会发布一个真正的Angular"方式来做这种事情当我发现自己在为这些操作材料库时的东西原因类型.

您需要使用 div 包装器包装您的选项并分配一个 templateRef #matOptionDiv 以便您可以在您的组件中使用它来获取您的选项下拉列表的父元素是 CDK 覆盖.

<mat-option *ngFor="let food of food" [value]="food.value">{{food.viewValue}}</mat-option>

然后使用mat-form-field上的点击事件触发组件中的一个方法来对齐覆盖

然后在你的组件中使用 @ViewChild 来获取 templateRef

import {Component, ViewChild} from '@angular/core';@ViewChild('matOptionDiv') _matOptionDiv:any;

然后创建您的方法来计算叠加层上的新 top 值并分配它... setTimout 是触发摘要循环更改所必需的.

positionDropDown(){让偏移Y =this._matOptionDiv.nativeElement.parentElement.parentElement.style.topsetTimeout(()=>{this._matOptionDiv.nativeElement.parentElement.parentElement.style.top = parseInt(offsetY.slice(0, -2))+40+'px'},0)}

这是一个非常hacky"的解决方案,并不漂亮,希望有人在某个时候会发布一个真正的Angular"解决方案来解决这个问题.

  • 不幸的是,在 mat-select 的源中进行了计算,以编程方式定义叠加层的顶部基于通过 _calculateOverlayOffsetY 的可视区域......这些都没有在 API 中公开,所以我无法正确"操作它,我担心 DOM 操作可能是唯一的方法.

https://github.com/angular/material2/blob/6d7f41739207e469e626963d64e661401629902d/src/lib/select/select.ts#L1154

这是 Stackblitz 供您查看.

https://stackblitz.com/edit/angular-nafuur?embed=1&file=app/select-overview-example.ts

修订

我对此进行了更多研究,并且只要您使用 Renderer2,DOM 操作在 Angular 中是可以接受的,因为它与 DOM 适配器接口并适当地"更新 DOM ......DOM 改变平台无关.

请参考此 YouTube 视频以了解更多信息.

不能碰这个!Max NgWizard 不应该对 DOM 做什么

<小时>

Stackblitz 代码更新如下

import {Component, ViewChild, ElementRef, Renderer2} from '@angular/core';@ViewChild('matOptionDiv') _matOptionDiv:ElementRef;构造函数(私有渲染器:Renderer2){}位置下拉(){让 offsetY = this._matOptionDiv.nativeElement.parentElement.parentElement.style.top;setTimeout(() => {//this._matOptionDiv.nativeElement.parentElement.parentElement.style.top = parseInt(offsetY.slice(0, -2))+40+'px'},0)this.renderer.setStyle(this.renderer.parentNode(this.renderer.parentNode(this._matOptionDiv.nativeElement)), 'top', parseInt(offsetY.slice(0, -2)) + 40 + 'px');});}

How to show options under select (Angular material 7)?

Something like default select:

解决方案

The "correct" answer is to use the disableOptionCentering on your mat-select, but even this only prevents the placeholder from being covered and does not mimic the basic native select.

<mat-select placeholder="Favorite food" disableOptionCentering>

It is strongly frowned upon to do DOM manipulation of the native element in Angular, but this unfortunately, is the only way I have found to do stuff like this...

  • Hopefully someone will post a true "Angular" way to do this kind of stuff as I find myself manipulating the material library for these types of reasons.

You will need to wrap your options with a div wrapper and assign a templateRef #matOptionDiv so that you can use this in your component to grab the parent element(s) of your option drop down which is the CDK overlay.

<div #matOptionDiv>
   <mat-option *ngFor="let food of foods" [value]="food.value">
      {{food.viewValue}}
   </mat-option>
</div> 

Then use the click event on mat-form-field to trigger a method in your component to align the overlay

<mat-form-field (click)="positionDropDown()">

Then in your component use @ViewChild to grab the templateRef

import {Component, ViewChild} from '@angular/core';

@ViewChild('matOptionDiv') _matOptionDiv:any;

Then create your method to calculate new top value on the overlay and assign it... the setTimout is necessary to trigger change with the digest cycle.

positionDropDown(){
  let offsetY = 
  this._matOptionDiv.nativeElement.parentElement.parentElement.style.top

  setTimeout(()=>{this._matOptionDiv.nativeElement.parentElement.parentElement.style.top = parseInt(offsetY.slice(0, -2))+40+'px'},0)
  }

This is a very "hacky" solution and is not pretty, hopefully someone at some point will post an answer with a true "Angular" solution to this question.

  • Unfortunately there are calculations happening in the source of the mat-select to programmatically define the top of the overlay based on the viewable area via _calculateOverlayOffsetY... none of this is exposed in the API so I am not able to manipulate it "correctly" and I fear DOM manipulation may be the only way.

https://github.com/angular/material2/blob/6d7f41739207e469e626963d64e661401629902d/src/lib/select/select.ts#L1154

Here is Stackblitz for your review.

https://stackblitz.com/edit/angular-nafuur?embed=1&file=app/select-overview-example.ts

Revision

I did some more research on this and DOM manipulation is acceptable in angular as long as you are using Renderer2 as it interfaces with the DOM adapter and updates the DOM "appropriately"... making the DOM changes platform independent.

Please reference this youTube video for more information.

Can't Touch This! What not to do to the DOM by Max NgWizard


Stackblitz code update below

import {Component, ViewChild, ElementRef, Renderer2} from '@angular/core';

@ViewChild('matOptionDiv') _matOptionDiv:ElementRef;

constructor(private renderer: Renderer2) { }

 positionDropDown() {
    let offsetY = this._matOptionDiv.nativeElement.parentElement.parentElement.style.top;

    setTimeout(() => {
      // this._matOptionDiv.nativeElement.parentElement.parentElement.style.top = parseInt(offsetY.slice(0, -2))+40+'px'},0)
      this.renderer.setStyle(this.renderer.parentNode(this.renderer.parentNode(this._matOptionDiv.nativeElement)), 'top', parseInt(offsetY.slice(0, -2)) + 40 + 'px');
    });
  }

这篇关于如何在选择下显示选项(Angular material 7)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆