【问题标题】:Injecting CSS based on config and flickering基于配置和闪烁的注入CSS
【发布时间】:2018-05-09 03:20:09
【问题描述】:

只是想知道是否有人知道如何解决这个问题。我将外部 CSS 链接添加到 AppComponent ngOnInit 的标题。它工作正常,但是页面在添加样式表之前会短暂闪烁并显示 html。我试图隐藏 html 直到链接注入之后,但仍然有相同的行为。这是代码

import { Component, OnInit, Inject, AfterViewInit, ViewEncapsulation, OnDestroy  }  from '@angular/core';
import { Router, NavigationStart, NavigationEnd } from '@angular/router';
import { Title }     from '@angular/platform-browser';

import { ConfigurationService } from './services/configuration.service';
import { SessionService } from './services/session.service';
import { DOCUMENT } from '@angular/platform-browser';

import './operators';
import { InjectCssService } from './services/injectcss.service';

/**
 * This class represents the main application component.
 */
@Component({
  selector: 'app-root',
  encapsulation: ViewEncapsulation.None,
  template: `
      <div [hidden]="isLoading" class="router-output">
        <router-outlet></router-outlet>
      </div>
  `
})
export class AppComponent implements OnInit, AfterViewInit, OnDestroy  {
  isLoading : boolean;
  configService: ConfigurationService;

  constructor(
    @Inject(DOCUMENT) private document,
    private configurationService: ConfigurationService,
    private injectCssService: InjectCssService,
    private sessionService: SessionService,
    private router: Router,
    private titleService: Title,
  ) {
    this.configService = configurationService;
    this.isLoading = configurationService.isLoading;
    sessionService.Initialize();

    titleService.setTitle(configurationService.config.title);
  }

  ngOnInit() {
    Object.keys(this.configurationService.config.cssUrls).map(url => {
      let head = this.document.getElementsByTagName('head')[0];
      let style = head.getElementsByTagName('link')[1];
      let link = this.injectCssService.createLink(this.configurationService.config.cssUrls[url]);
      console.log(link);
      head.appendChild(link);
    });
  }

  ngOnDestroy() {
    this.isLoading = false;
  }
}

【问题讨论】:

  • 您遇到的现象称为 FOUC(无样式内容的闪现)。每当您在加载 DOM 后向页面动态添加外部样式时,您都会遇到这种情况。它们在您的配置中是如何配置的?它们只是一个静态列表还是以某种方式动态? en.wikipedia.org/wiki/Flash_of_unstyled_content
  • 我可以想到两种方法来解决这个问题:1. 服务器端渲染或 2. 数据解析守卫和路由
  • @DanielWSrimpel 谢谢。它是动态列表,因此数组可以有 N 个样式表。
  • @pixelbits 我想到了服务器端渲染。可以详细说明 2。不太确定我是否遵循。
  • 根据您上面的用法,该列表似乎不是可观察的。这个列表在编译代码时是否已知?

标签: angular typescript dom stylesheet


【解决方案1】:

Angular 在呈现页面之前通过 Web 服务检索数据来异步加载数据。在页面加载样式表、调用 web 服务和渲染 DOM 时,可能会出现明显的闪烁。

为了解决这个问题,您可以设置数据解析保护,以便在路由更改之前完全加载数据。这允许组件加载和渲染数据而无需等待;从而显着减少闪烁效果。

这是一个示例路线:

export const routes: Routes = [
    { path: '', component: MainComponent, resolve: { data: MyDataResolver } 
}]

MyDataResolver.ts

import { Injectable } from '@angular/core';
import { Resolve, ActivatedRouteSnapshot } from '@angular/router';
import { MyDataService } from './mydata.service';

@Injectable()
export class MyDataResolver implements Resolve<MyData> {

  constructor(private myDataService: MyDataService) {}

  resolve(route: ActivatedRouteSnapshot) {
    return this.myDataService.getData();
  }
}

app.module.ts

@NgModule({
  ...
  providers: [
    MyDataService,
    MyDataResolver
  ]
})
export class AppModule {}

ma​​in.component.ts

@Component()
export class MainComponent implements OnInit {

  mydata: any;

  constructor(private route: ActivatedRoute) {}

  ngOnInit() {
    this.mydata= this.route.snapshot.data['data'];
  }
}

有关数据解析器的更多信息:https://blog.thoughtram.io/angular/2016/10/10/resolving-route-data-in-angular-2.html

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-12
    • 2016-06-05
    • 2018-05-14
    • 2014-08-17
    相关资源
    最近更新 更多