Angular 在实现自定义主题后不会更新视图

问题描述 投票:0回答:1

我是Angluar和前端开发的新手,但我正在开发一个相当大的项目,最近我不得不在其中实现自定义主题,问题是在我完成它之后,它在你之后停止更新HTML更改

*ngIf
值。

我怀疑我实现自定义主题的方式可能有问题,所以我将开始分享这部分代码: 样式.scss

/* You can add global styles to this file, and also import other style files */
@import 'custom-theme.scss';

html,
body {
    height: 100%;
}

body {
    margin: 0;
    font-family: Roboto, "Helvetica Neue", sans-serif;
}

自定义主题.scss

@use '@angular/material' as mat;
@include mat.core();

$light-primary: mat.define-palette(mat.$blue-palette);
$light-accent: mat.define-palette(mat.$indigo-palette);
$light-warn: mat.define-palette(mat.$red-palette);

$light-theme: mat.define-light-theme((color:(primary: $light-primary,
                accent: $light-accent,
                warn: $light-warn )));

@include mat.all-component-themes($light-theme);

.dark-theme {
    $dark-primary: mat.define-palette(mat.$deep-orange-palette);
    $dark-accent: mat.define-palette(mat.$amber-palette);
    $dark-warn: mat.define-palette(mat.$red-palette);

    $dark-theme: mat.define-dark-theme((color:(primary: $dark-primary,
                    accent: $dark-accent,
                    warn: $dark-warn )));

    @include mat.all-component-colors($dark-theme);
}

.light-background {
    background-color: rgba(0, 0, 0, 0.02);
}

.dark-background {
    background-color: #303030;
}

这就是我更改主题的方式: header.component.ts:

constructor(
    public cookieService: CookieService,
    public dialog: MatDialog,
    public router: Router,
    public translateService: TranslateService,
    private responsive: BreakpointObserver,
    private render: Renderer2,
    @Inject(DOCUMENT) private document: Document,
    media: MediaMatcher,
  ) {
    this.mobileQuery = media.matchMedia('(max-width: 600px)');
    this.langs = this.translateService.getLangs();
    this.selectedLang = this.translateService.currentLang;
    this.userId = cookieService.get('UserId');
  }

  ngOnInit() {
    this.responsive.observe(['(min-width: 1022px)'])
      .subscribe(result => {
        this.isMobile = result.matches;
      });
  }

  changedTheme(): void {
    this.render.removeClass(this.document.body, 'light-theme');
    this.render.removeClass(this.document.body, 'dark-theme');
    this.render.removeClass(this.document.body, 'light-background');
    this.render.removeClass(this.document.body, 'dark-background');
    this.render.addClass(this.document.body, this.selectedTheme.toLowerCase() + '-theme');
    this.render.addClass(this.document.body, this.selectedTheme.toLowerCase() + '-background');
  }

函数

changedTheme
在另外两个组件
app.component.ts
settings.component.ts
中使用(实际上是复制和粘贴),因为我也需要管理这两个组件上的主题。

我在想是否有可能“发出”一个事件来改变主题,但我不确定这是否是不好的做法,这不是这个问题的主要目标。 但是,我需要一些帮助。我没有任何其他专门更改或手动更新视图的代码。

PS:必须放置

.light-background
dark-background
类,因为主题由于某种原因不会改变背景

更新

好吧,我使用了 git,然后在编写主题之前返回,问题仍然存在。重新启动计算机,重新下载

node_modules
并在多个浏览器中进行测试,即使没有主题,问题仍然存在。现在我真的不知道该怎么办了。唯一的区别是它删除了
@angular/flex-layout
但是,即使我强迫它保留它,问题仍然存在。我应该去哪里调试这种问题?

更新2

调试提交后,几乎一整天的工作,我都完成了。问题不在于主题,而在于我的

header.html
组件。我必须用它做一些技巧,使其能够响应移动设备和桌面设备,它们有不同的界面,以及导致某些东西损坏的原因。不知道为什么或是什么,但找到另一种方法来完成响应部分比解决我创建的这个问题更容易。 这是损坏的代码:

<div style="display: contents;">
  <mat-toolbar color="primary" class="header-top">
    <div style="display: contents;" *ngIf="!isMobile">
      <button mat-icon-button (click)="snav.toggle()" class="icon-button">
        <img class="icon" src="../assets/imgs/1315254.png" alt="profile" />
      </button>

      <span class="toolbar-text" (click)="goToPage('home')">{{ cookieService.get('Username') }}</span>

      <button mat-icon-button (click)="goToPage('access')" *ngIf="!userId">
        <mat-icon>manage_accounts</mat-icon>
      </button>
    </div>

    <div style="display: contents;" *ngIf="isMobile">
      <span class="toolbar-text" (click)="goToPage('home')">FindME!</span>
      <span class="spacer"></span>

      <mat-form-field style="margin-top: 20px;" *ngIf="isDevMode()">
        <mat-select [(value)]="selectedLang" (valueChange)="changedLanguage()" id="lang-select">
          <mat-option *ngFor="let lang of langs" [value]="lang">
            {{ lang.split('-')[0].toUpperCase() }}
          </mat-option>
        </mat-select>
      </mat-form-field>

      <button mat-icon-button (click)="goToPage('access')" *ngIf="!userId">
        <mat-icon>manage_accounts</mat-icon>
      </button>
      <button mat-icon-button [matMenuTriggerFor]="notifications" *ngIf="userId">
        <mat-icon>notifications</mat-icon>
      </button>
      <button mat-icon-button [matMenuTriggerFor]="chat" *ngIf="userId">
        <mat-icon>chat</mat-icon>
      </button>
      <button mat-icon-button class="icon-button" [matMenuTriggerFor]="menu" *ngIf="userId">
        <img class="icon" src="../assets/imgs/1315254.png" alt="profile" />
      </button>

      <!-- Menu -->
      <mat-menu #menu="matMenu">
        <button mat-menu-item (click)="goToPage('profile')">
          <mat-icon>account_circle</mat-icon>
          <span>{{ 'HEADER.PROFILE' | translate }}</span>
        </button>
        <button mat-menu-item (click)="goToPage('settings')">
          <mat-icon>settings</mat-icon>
          <span>{{ 'HEADER.SETTINGS' | translate }}</span>
        </button>
        <button mat-menu-item (click)="logout()">
          <mat-icon>logout</mat-icon>
          <span>{{ 'HEADER.LOGOUT' | translate }}</span>
        </button>
      </mat-menu>

      <!-- Notifications -->
      <mat-menu #notifications="matMenu">
        <h1 *ngIf="userNotifications == null">{{ "HEADER.NO-NEW-NOTIFICATIONS" | translate }}</h1>
        <div *ngIf="userNotifications != null">
          <button mat-menu-item (click)="goToPage('profile')">
            <mat-icon>notifications</mat-icon>
          </button>
        </div>
      </mat-menu>

      <!-- Chat -->
      <mat-menu #chat="matMenu">
        <h1 *ngIf="chats == null">{{ "HEADER.NO-NEW-CONVERSATION" | translate }}</h1>
        <div *ngIf="chats != null">
          <button mat-menu-item (click)="goToPage('profile')">
            <mat-icon>chat</mat-icon>
          </button>
        </div>
      </mat-menu>

      <button mat-icon-button aria-label="icon-button with share icon" (click)="goToPage('about')">
        <mat-icon>help</mat-icon>
      </button>
    </div>
  </mat-toolbar>

  <mat-sidenav-container class="example-sidenav-container">
    <mat-sidenav #snav [mode]="'over'" fixedTopGap="102">
      <mat-nav-list>
        <mat-selection-list role="list">
          <mat-divider></mat-divider>
          <mat-list-item role="button" *ngIf="userId">
            <a (click)="goToPage('notifications')">
              {{ 'NOTIFICATIONS' | translate }}
            </a>
          </mat-list-item>
          <mat-divider></mat-divider>
          <mat-list-item role="button" *ngIf="userId">
            <a (click)="goToPage('chat')">
              {{ 'CHATS' | translate }}
            </a>
          </mat-list-item>
          <mat-divider></mat-divider>
        </mat-selection-list>
      </mat-nav-list>
    </mat-sidenav>
    <mat-sidenav-content>
      <router-outlet></router-outlet>
    </mat-sidenav-content>
  </mat-sidenav-container>
</div>

通过将其返回到“移动兼容”之前解决了这个问题:

<mat-toolbar color="primary" class="header-top">
  <span class="toolbar-text" (click)="goToPage('home')">FindME!</span>
  <span class="spacer"></span>
  <mat-form-field>
    <mat-select [(value)]="selectedLang" (valueChange)="changedLanguage()" id="lang-select">
      <mat-option *ngFor="let lang of langs" [value]="lang">
        <!-- {{ lang | translate }} -->
        {{ lang.split('-')[0].toUpperCase() }}
      </mat-option>
    </mat-select>
  </mat-form-field>

  <button mat-icon-button (click)="goToPage('access')" *ngIf="!cookieService.get('UserId')">
    <mat-icon>manage_accounts</mat-icon>
  </button>
  <button mat-icon-button [matMenuTriggerFor]="notifications" *ngIf="cookieService.get('UserId')">
    <mat-icon>notifications</mat-icon>
  </button>
  <button mat-icon-button [matMenuTriggerFor]="chat" *ngIf="cookieService.get('UserId')">
    <mat-icon>chat</mat-icon>
  </button>
  <button mat-icon-button class="icon-button" [matMenuTriggerFor]="menu" *ngIf="cookieService.get('UserId')">
    <img class="icon" src="../assets/imgs/1315254.png" alt="profile" />
  </button>

  <!-- Menu -->
  <mat-menu #menu="matMenu">
    <button mat-menu-item (click)="goToPage('profile')">
      <mat-icon>account_circle</mat-icon>
      <span>{{ 'HEADER.PROFILE' | translate }}</span>
    </button>
    <button mat-menu-item (click)="goToPage('settings')">
      <mat-icon>settings</mat-icon>
      <span>{{ 'HEADER.SETTINGS' | translate }}</span>
    </button>
    <button mat-menu-item (click)="logout()">
      <mat-icon>logout</mat-icon>
      <span>{{ 'HEADER.LOGOUT' | translate }}</span>
    </button>
  </mat-menu>
  <!-- Notifications -->
  <mat-menu #notifications="matMenu">
    <h1 *ngIf="userNotifications == null">{{ "HEADER.NO-NEW-NOTIFICATIONS" | translate }}</h1>
    <div *ngIf="userNotifications != null">
      <button mat-menu-item (click)="goToPage('profile')">
        <mat-icon>notifications</mat-icon>
      </button>
    </div>
  </mat-menu>
  <!-- Chat -->
  <mat-menu #chat="matMenu">
    <h1 *ngIf="chats == null">{{ "HEADER.NO-NEW-CONVERSATION" | translate }}</h1>
    <div *ngIf="chats != null">
      <button mat-menu-item (click)="goToPage('profile')">
        <mat-icon>chat</mat-icon>
      </button>
    </div>
  </mat-menu>

  <button mat-icon-button aria-label="icon-button with share icon" (click)="goToPage('about')">
    <mat-icon>help</mat-icon>
  </button>
</mat-toolbar>

所以我觉得自己真的很愚蠢,很抱歉浪费了你的时间。也许我会删除这个问题,因为它对任何人都没有帮助,但是,是的,感谢您的帮助和关注!!

angular typescript angular-material theming
1个回答
1
投票

这真的很奇怪,我尝试重现该问题,但你的代码运行得很好,也许可以在 stackblitz 中复制该问题并分享回来!

代码

import { Component, Inject, Renderer2 } from '@angular/core';
import { MatIconModule } from '@angular/material/icon';
import { MatDividerModule } from '@angular/material/divider';
import { MatButtonModule } from '@angular/material/button';
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
import { DOCUMENT } from '@angular/common';
import { FormsModule } from '@angular/forms';

/**
 * @title Basic buttons
 */
@Component({
  selector: 'button-overview-example',
  templateUrl: 'button-overview-example.html',
  styleUrls: ['button-overview-example.css'],
  standalone: true,
  imports: [
    MatButtonModule,
    MatDividerModule,
    MatIconModule,
    MatSlideToggleModule,
    FormsModule,
  ],
})
export class ButtonOverviewExample {
  isDark = false;
  selectedTheme: string;

  constructor(
    private render: Renderer2,
    @Inject(DOCUMENT) private document: Document
  ) {}

  toggleTheme() {
    this.selectedTheme = this.isDark ? 'dark' : 'light';
    this.changedTheme();
  }

  changedTheme(): void {
    this.render.removeClass(this.document.body, 'light-theme');
    this.render.removeClass(this.document.body, 'dark-theme');
    this.render.removeClass(this.document.body, 'light-background');
    this.render.removeClass(this.document.body, 'dark-background');
    this.render.addClass(
      this.document.body,
      this.selectedTheme.toLowerCase() + '-theme'
    );
    this.render.addClass(
      this.document.body,
      this.selectedTheme.toLowerCase() + '-background'
    );
  }
}

html

Light
<mat-slide-toggle [(ngModel)]="isDark" (ngModelChange)="toggleTheme()"
  >Dark</mat-slide-toggle
>
<br />

<section>
  <div class="example-label">Basic</div>
  <div class="example-button-row">
    <button mat-button>Basic</button>
    <button mat-button color="primary">Primary</button>
    <button mat-button color="accent">Accent</button>
    <button mat-button color="warn">Warn</button>
    <button mat-button disabled>Disabled</button>
    <a mat-button href="https://www.google.com/" target="_blank">Link</a>
  </div>
</section>
<mat-divider></mat-divider>
<section>
  <div class="example-label">Raised</div>
  <div class="example-button-row">
    <button mat-raised-button>Basic</button>
    <button mat-raised-button color="primary">Primary</button>
    <button mat-raised-button color="accent">Accent</button>
    <button mat-raised-button color="warn">Warn</button>
    <button mat-raised-button disabled>Disabled</button>
    <a mat-raised-button href="https://www.google.com/" target="_blank">Link</a>
  </div>
</section>
<mat-divider></mat-divider>
<section>
  <div class="example-label">Stroked</div>
  <div class="example-button-row">
    <button mat-stroked-button>Basic</button>
    <button mat-stroked-button color="primary">Primary</button>
    <button mat-stroked-button color="accent">Accent</button>
    <button mat-stroked-button color="warn">Warn</button>
    <button mat-stroked-button disabled>Disabled</button>
    <a mat-stroked-button href="https://www.google.com/" target="_blank"
      >Link</a
    >
  </div>
</section>
<mat-divider></mat-divider>
<section>
  <div class="example-label">Flat</div>
  <div class="example-button-row">
    <button mat-flat-button>Basic</button>
    <button mat-flat-button color="primary">Primary</button>
    <button mat-flat-button color="accent">Accent</button>
    <button mat-flat-button color="warn">Warn</button>
    <button mat-flat-button disabled>Disabled</button>
    <a mat-flat-button href="https://www.google.com/" target="_blank">Link</a>
  </div>
</section>
<mat-divider></mat-divider>
<section>
  <div class="example-label">Icon</div>
  <div class="example-button-row">
    <div class="example-flex-container">
      <button
        mat-icon-button
        aria-label="Example icon button with a vertical three dot icon"
      >
        <mat-icon>more_vert</mat-icon>
      </button>
      <button
        mat-icon-button
        color="primary"
        aria-label="Example icon button with a home icon"
      >
        <mat-icon>home</mat-icon>
      </button>
      <button
        mat-icon-button
        color="accent"
        aria-label="Example icon button with a menu icon"
      >
        <mat-icon>menu</mat-icon>
      </button>
      <button
        mat-icon-button
        color="warn"
        aria-label="Example icon button with a heart icon"
      >
        <mat-icon>favorite</mat-icon>
      </button>
      <button
        mat-icon-button
        disabled
        aria-label="Example icon button with a open in new tab icon"
      >
        <mat-icon>open_in_new</mat-icon>
      </button>
    </div>
  </div>
</section>
<mat-divider></mat-divider>
<section>
  <div class="example-label">FAB</div>
  <div class="example-button-row">
    <div class="example-flex-container">
      <div class="example-button-container">
        <button
          mat-fab
          color="primary"
          aria-label="Example icon button with a delete icon"
        >
          <mat-icon>delete</mat-icon>
        </button>
      </div>
      <div class="example-button-container">
        <button
          mat-fab
          color="accent"
          aria-label="Example icon button with a bookmark icon"
        >
          <mat-icon>bookmark</mat-icon>
        </button>
      </div>
      <div class="example-button-container">
        <button
          mat-fab
          color="warn"
          aria-label="Example icon button with a home icon"
        >
          <mat-icon>home</mat-icon>
        </button>
      </div>
      <div class="example-button-container">
        <button
          mat-fab
          disabled
          aria-label="Example icon button with a heart icon"
        >
          <mat-icon>favorite</mat-icon>
        </button>
      </div>
    </div>
  </div>
</section>
<mat-divider></mat-divider>
<section>
  <div class="example-label">Mini FAB</div>
  <div class="example-button-row">
    <div class="example-flex-container">
      <div class="example-button-container">
        <button
          mat-mini-fab
          color="primary"
          aria-label="Example icon button with a menu icon"
        >
          <mat-icon>menu</mat-icon>
        </button>
      </div>
      <div class="example-button-container">
        <button
          mat-mini-fab
          color="accent"
          aria-label="Example icon button with a plus one icon"
        >
          <mat-icon>plus_one</mat-icon>
        </button>
      </div>
      <div class="example-button-container">
        <button
          mat-mini-fab
          color="warn"
          aria-label="Example icon button with a filter list icon"
        >
          <mat-icon>filter_list</mat-icon>
        </button>
      </div>
      <div class="example-button-container">
        <button
          mat-mini-fab
          disabled
          aria-label="Example icon button with a home icon"
        >
          <mat-icon>home</mat-icon>
        </button>
      </div>
    </div>
  </div>
</section>

堆栈闪电战

© www.soinside.com 2019 - 2024. All rights reserved.