Angular 11 - 如何使用Angular Material样式化文件输入按钮

3

我看到了很多关于这个问题的问题,但是没有一个解决了我的问题。

我的情况:

Angular 11,Angular Material 8和一个文件输入框,就像这样:

<div class="form-group">
    <input #myInput type="file" formControlName="fi"
                     id="fi" name="fi" (change)="postMethod($event.target.files)">
</div>

我需要做的事情: 我需要自定义这个按钮的颜色、文本和大小。

File input button style

我该如何自定义它?谢谢。


你有任何问题吗? - R3tep
@R3tep 我该如何使用Angular Material自定义按钮的大小、颜色和文本? - Iñigo
只需使用CSS样式。 - Dani R
你尝试过这个答案吗?https://dev59.com/eVQK5IYBdhLWcg3wBrUK - Chellappan வ
1
你可以阅读Angular Material的文档。如果在实现过程中遇到任何问题,展示你的尝试以及问题以获得帮助。另外,如果你需要一个特定的样式,你需要编写 CSS。 - R3tep
3个回答

6

最终解决方案(适用于Angular Material和Bootstrap):

我设置了3个不同的组件

  1. 可见的按钮(可以是Angular Material或Bootstrap,如下所示)
  2. 文件输入框
  3. 包含文件名的标签

HTML代码:

<div>
  <button #file class="btn btn-light">Examinate</button>
  <div style="display: inline-block">
      <input #myInput formControlName="file"
      id="file" name="file" (change)="postMethod($event.target.files)" type="file"/>
      <p>{{file}}</p>
  </div>
</div> 

CSS(层叠样式表)

使用CSS,我强制输入覆盖在按钮上,并设置opacity=0以使按钮可见。

- 按钮:

float:left; 
position:absolute; 
z-index:-1;

- 输入:

opacity: 0; //Not visible
font-size: 0;
//Button dimensions
width: 90px; 
height: 37px; 
float: left; 

- 输入(悬停):

cursor: pointer;

- 标签:

float: left; 
margin-left: 6px; 
margin-top: 7px;

以下是最终结果:

自定义按钮


2

您无法直接样式化input type file,最佳方法是创建与input type file相对应的覆盖元素。

使用Material,您几乎可以样式化所有与Material相关的内容,当然,您可以将Material中的类添加到自定义组件中,但这不是Material的用途。

简单的例子,您不应该这样做:

<div class="mat-card"></div>

如果您能做到这一点:
<mat-card></mat-card>

同样地,如果你想让输入框呈现材料风格,你需要创建类似这样的内容:
HTML:
<mat-card class="input-container">
  <button #file mat-flat-button color="primary">Examinar...
      <input multiple (change)="onFileSelected($event)" style="opacity: 0; position:absolute; left:0px; top:0px; width:100%; height:100%;" type="file"/>
  </button>
  {{files|json}}
</mat-card>

TS:

  files: string[] = [];
  onFileSelected(event) {
    if (event.target.files.length > 0) {
      for (let i = 0; i < event.target.files.length; i++) {
        this.files.push(event.target.files[i].name);
        console.log(event.target.files[0].name);
      }
    }
  }

CSS:

.input-container {
  position:relative;
}

这只是一个简单的例子。


但我仍然更喜欢使用像https://www.npmjs.com/package/ngx-dropzone这样的npm包。


谢谢你的回答。我尝试了你的代码,但是当我点击按钮时,触发的是onSubmit()方法,而不是打开文件选择器,这正是我需要的点击事件行为。我猜想无法实现我所需的功能。 - Iñigo
没有样本项目很难确定问题的原因。但是你可以尝试将不透明度设置为1,以确保输入框在正确的位置,而不是覆盖在按钮上面,这样才能正常工作。 - Jacek Ratajewski
似乎输入框不能在按钮内部 链接。将尝试使用 CSS 将它们结合起来。 - Iñigo

-2
在你的 css/scss/sass 中:
#fi {
  background-color: pink;
  ...
}

使用Angular Material不是一个好的方式来为单个按钮设置样式。如果您想要为组设置样式,我建议阅读这篇文章:https://material.angular.io/guide/customizing-component-styles

编辑:

类型为file的输入元素不容易进行样式设置。

这里有一个Plunkr示例,展示如何实现:

.fileContainer {
    overflow: hidden;
    position: relative;
    cursor: pointer;
    background-color: pink;
}

.fileContainer [type=file] {
    cursor: inherit;
    display: block;
    font-size: 999px;
    filter: alpha(opacity=0);
    min-height: 100%;
    min-width: 100%;
    opacity: 0;
    position: absolute;
    right: 0;
    text-align: right;
    top: 0;
}
    <label class="fileContainer">
      File upload
      <input type="file"/>
    </label>


我只需要为输入框的按钮设置样式。您提供的解决方案会将整个输入框(包括上面的文本)都进行样式设置。 - Iñigo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接