我已经为此苦苦挣扎。解决方案比您想象的要简单得多……几乎所有 Angular 中的东西都可以动画,我们可以用几行非常简单的动画代码来解决这个问题……
在名为 sidenav.animations.ts 的文件中
您将创建一个动画来为 的宽度在 200px 和 60px 之间设置动画
您将创建第二个动画,以使 的左侧边距介于 201 像素和 61 像素之间。
./sidenav.animations.ts
import {
animate,
state,
style,
transition,
trigger,
} from '@angular/animations';
/*
* animation: sideNaveAnimation
* trigger: 'openClose'
*
* comments: sets the width of an element to 200px when 'open' and to 60px
* when closed. Animates in between these two states over '0.3s'
*/
export const sideNavAnimation = trigger('openCloseSidenav', [
// ...
state('open', style({
width: '200px',
})),
state('closed', style({
width: '60px',
})),
transition('open <=> closed', [
animate('0.3s')
]),
]);
/*
* animation: sideNavContainerAnimation
* trigger: 'openCloseSidenavContent'
*
* comments: Sets the margin-left to 201px when "open" and 61px when "closed".
*/
export const sideNavContainerAnimation = trigger('openCloseSidenavContent', [
state('open', style({
'margin-left': '201px',
})),
state('closed', style({
'margin-left': '61px',
})),
transition('open <=> closed', [
animate('0.3s')
]),
]);
在你的 app.component.ts...
您将导入两个动画并在动画数组中使用它们,这将允许您在 app.component.html 中使用 sidenav.animations.ts(“openCloseSidenav”和“openCloseSidenavContent”)中定义的触发器
您将创建一个布尔值 (isOpen) 来跟踪 sidenav 所处的状态
您将创建一个名为 toggle() 的函数,它将在 true 和 false 之间切换变量 isOpen。该函数将通过按下 app.component.html 中的按钮调用
./app.component.ts
不要忘记将您的 MatSidenavModule、MatButtonsModule、MatIconModule、MatListModule 和 BrowserAnimationsModule 也导入到您的 app.module.ts 中,否则您将无法在 app.component 中的任何位置使用 或其中的任何内容.html
import { Component } from '@angular/core';
//...
import { sideNavAnimation, sideNavContainerAnimation } from './sidenav.animations';
//...
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
animations: [sideNavAnimation, sideNavContainerAnimation]
})
export class AppComponent {
isOpen = true;
toggle() {
this.isOpen = !this.isOpen;
}
//...
}
在你的 app.component.html...
您将使用放置在 sidenav 某处的按钮调用 toggle()。
您将在 上放置动画触发器:'openCloseSidenav',并带有一个 表达式,该表达式将选择两个已定义状态中的哪一个(“打开”或“关闭”,如sidenav.animations.ts) 元素应该处于基于变量 isOpen 的状态并在状态之间进行动画处理。
您将使用与上述相同的表达式将动画触发器:'openCloseSidenavContent' 放置在 上。
./app.component.html
<mat-sidenav-container>
<mat-sidenav [@openCloseSidenav]="isOpen ? 'open' : 'closed'" mode="side" opened role="navigation">
<mat-nav-list>
<!-- Place nav links here -->
<button type="button" aria-label="Toggle nav" mat-icon-button (click)="toggle()">
<mat-icon aria-label="Side nav toggle icon">menu</mat-icon>
</button>
</mat-nav-list>
</mat-sidenav>
<mat-sidenav-content [@openCloseSidenavContent]="isOpen ? 'open' : 'closed'">
<router-outlet></router-outlet>
</mat-sidenav-content>
</mat-sidenav-container>
剩下的你自己填,我的里面有如下图。
...我正在使用变量 isOpen 来决定是否应显示图标旁边的文本..我很快会在 标签中添加动画以使这些动画在toggle() 被调用并且 isOpen 发生变化,否则我会将动画时间缩短到 0.0 秒,以便它在两种状态之间立即捕捉...
...然而,即使标签中没有 *ngIf="isOpen" 也可以正常工作...
<a mat-list-item (click)="signOut()">
<span class="app-nav-list-icon">
<mat-icon matListIcon class="app-nav-list-icon">
<fa-icon icon="sign-out-alt"style="color: #808DE1;"></fa-icon>
</mat-icon>
</span>
<mat-chip-list *ngIf="isOpen" style="padding-left: .5em;">
<mat-chip>Logout</mat-chip>
</mat-chip-list>
</a>
...这里的重点是 简单 动画可用于控制应用程序各个方面的行为和外观...
请访问 https://angular.io/guide/animations 了解有关其工作原理的更多详细信息...