角度不正确的边距 - 左侧应用于Sidenav内容

时间:2018-03-08 15:15:20

标签: css angular angular-material

我有一个使用Angular Material的Angular项目,但我遇到了一个错误,有时候mat-sidenav-content有一个margin-left: 365px;应用于它,导致sidenav和the之间有一个很大的空白区域主要内容。

enter image description here

enter image description here

当我加载应用程序时,大约50%的时间都会发生,margin-left已应用。其余的时间都很好。 然而,如果我点击菜单按钮隐藏菜单并再次显示,那么它会被修复,直到我重新加载应用程序。

我觉得这可能与我的isMobile()功能和竞争条件有关,但不确定。

在我的app.component.html

<div class="app-container">
    <mat-toolbar color="primary">
        <mat-toolbar-row>
            ...
        </mat-toolbar-row>
    </mat-toolbar>
    <mat-sidenav-container class="mat-container" >
        <mat-sidenav #sidenav class="mat-sidenav" [opened]="!isMobile()" [mode]="isMobile() ? 'over': 'side'" style="background: rgb(30, 136, 229);">
            <mat-nav-list class="mat-nav-list" role="list" style="padding-top: 0px;border-top-width: thin;border-top: white;border-top-style: solid;">
                ...
            </mat-nav-list>
        </mat-sidenav>

        <!--The magin-left is being applied here-->
        <mat-sidenav-content>
            <router-outlet></router-outlet>
        </mat-sidenav-content>

    </mat-sidenav-container>

    <mat-toolbar style="padding: 0px;background: #e9ecef;">
        <mat-toolbar-row>
            ...
        </mat-toolbar-row>
    </mat-toolbar>
</div>

在我的app.component.ts

export class AppComponent implements OnInit {

    private mediaMatcher: MediaQueryList = matchMedia(`(max-width: ${SMALL_WIDTH_BREAKPOINT}px)`);

    @ViewChild('sidenav') public sidenav: MatSidenav;

    constructor(zone: NgZone) {
        this.mediaMatcher.addListener(mql => zone.run(() => this.mediaMatcher = mql));
    }

    public ngOnInit(): void {
        this.sidenav.open();
    }

    isMobile(): boolean{
        return this.mediaMatcher.matches;
    }
}

修改:在ngAfterViewInit()内,我收到this.sidenav._width,有时为365,有时为167

我可能会稍微缩小我的问题范围。我的mat-nav-list里面有一个

<sidenav-group [icon]="'local_atm'" [label]="'Deposits'" [currentRoute]="currentRoute"
                            (changeRouteOutput)="changeRoute($event, false)">
</sidenav-group>

只有当我有这个组件时才会发生。

<a class="mat-list-item" mat-list-item="" role="listitem" (click)="toggleBody()"  style="color: white;">
    <div class="mat-list-item-content" style="display: flex; flex: 1; padding-left: 0px;">
        <div class="mat-list-item-ripple mat-ripple"></div>
        <div class="mat-list-text"></div>
        <mat-icon mat-list-icon>{{icon}}</mat-icon>
        {{label}}
        <span class="example-spacer"></span>
        <i class="material-icons" *ngIf="!displayBody">keyboard_arrow_down</i>
        <i class="material-icons" *ngIf="displayBody">keyboard_arrow_up</i>
    </div>
</a>

<div *ngIf="displayBody">
    <!-- Search -->
    <sidenav-element [icon]="'search'" [label]="'Search'" [route] ="'deposit/search'" [currentRoute]="currentRoute"
                    (changeRouteOutput)="changeRoute($event)">
    </sidenav-element>

    <!-- Cheque -->
    <sidenav-element [label]="'Cheque'" [route] ="'deposit/cheque'" [currentRoute]="currentRoute"
                    (changeRouteOutput)="changeRoute($event)">
    </sidenav-element>

    <!-- Pre-Authorization -->
    <sidenav-element  [label]="'Pre-Authorization'" [route] ="'deposit/pre-auth'" [currentRoute]="currentRoute"
        (changeRouteOutput)="changeRoute($event, false)">
    </sidenav-element>
</div>

我可以添加尽可能多的sidenav-element,但只有当我sidenav-group

时它才能正常工作

7 个答案:

答案 0 :(得分:7)

使用自动调整大小

    private void GetUsers()
     {
         OriginatorDropDown.Items.Clear();
         OriginatorDropDown.DataSource = GetUserData();
         OriginatorDropDown.DataBind();


using (PrincipalContext pc = new PrincipalContext(ContextType.Domain))
         foreach (ListItem ltItem in OriginatorDropDown.Items)
         {
             if (ltItem.Text != String.Empty)
             {


                     UserPrincipal up = UserPrincipal.FindByIdentity(pc, IdentityType.SamAccountName
,ltItem.Text);
                     if (up != null)
                     {
                         ltItem.Text = up.DisplayName;
                     }


             }
         }
     }

答案 1 :(得分:3)

看起来我发现了这个问题。在sidenav-group里面我有

<i class="material-icons" *ngIf="!displayBody">keyboard_arrow_down</i>
<i class="material-icons" *ngIf="displayBody">keyboard_arrow_up</i>

什么时候应该

<mat-icon mat-list-icon *ngIf="!displayBody">keyboard_arrow_down</mat-icon>
<mat-icon mat-list-icon *ngIf="displayBody">keyboard_arrow_up</mat-icon>

由于某种原因,<i>有时会插入额外的空间。

答案 2 :(得分:0)

我有类似的问题,已通过设置

修复
mat-sidenav-content {
    margin-left: 0 !important;
    flex: 1 1 auto;
}

mat-sidenav {
    flex: 0 1 auto;
}

[style.position]="sidenav.opened ? 'initial' : 'absolute'"一起 和 flex到mat-sidenav-container

答案 3 :(得分:0)

此错误是由于图标引起的。在连接缓慢后重新加载(清除缓存)后,angular将开始使用图标名称渲染字符串。由于字符串大于完全渲染的图标,因此将有多余的空间。重新加载后,由于该图标已经在设备存储中,因此不会发生。

我的解决方案是固定边栏宽度的值。

答案 4 :(得分:0)

这就是我想出的(使用angular的flex-layout):

<div fxLayout="column" style="position: absolute; top: 0; bottom: 0; left: 0; right: 0;">
  <mat-toolbar fxFlex="none">
    <div fxFlex="grow">
      <button mat-button (click)="sidenav1.toggle()">toggle nav1</button>
    </div>
    <div fxFlex="none">
      <button mat-button (click)="sidenav2.toggle()">toggle nav2</button>
    </div>
  </mat-toolbar>
  <mat-sidenav-container fxFlex="grow" fxLayout="row">
    <mat-sidenav opened mode="side" #sidenav1 fxFlex="none"
        [style.position]="sidenav1.mode !== 'over' && sidenav1.opened ? 'relative' : 'absolute'"
        style="width: 240px; background-color: red;">
      nav1
    </mat-sidenav>
    <mat-sidenav opened mode="over" position="end" #sidenav2 fxFlex="none"
        [style.position]="sidenav2.mode !== 'over' && sidenav2.opened ? 'relative' : 'absolute'"
        style="width: 240px; background-color: blue;">
      nav2
    </mat-sidenav>
    <mat-sidenav-content fxFlex="grow" style="background-color: green;">
      content
    </mat-sidenav-content>
  </mat-sidenav-container>
</div>
.mat-sidenav-content {
  margin-left: 0 !important;
}

在台式机和移动设备:)上完美运行

编辑:Stackblitz: https://stackblitz.com/edit/angular-r13fve

答案 5 :(得分:0)

setTimeout 的解决方法对我有用

export class AppComponent implements  AfterViewInit {

  @ViewChild('sidenav') 
  private sidenav: MdSidenav;

  ngAfterViewInit(): void {
    setTimeout(() => {
      this.sidenav.open();
    }, 250);
  }
}

来源: https://github.com/angular/components/issues/6743#issuecomment-327416089

答案 6 :(得分:0)

很明显,这个问题可能出现在不同的情况下。但共同点是它们都通过 CSS 导致 mat-sidenav 的计算宽度发生变化。

就我而言,mat-sidenav 具有固定宽度和 padding: 16pxmat-sidenav-content 有时会移动 32 像素。我的猜测是默认情况下 box-sizing: content-box。但是我的重置 CSS 将所有元素都更改为 border-box。我通过将 border-box 显式应用于 mat-sidenav 来修复它。