我在一个应用程序上工作,它有一个主视图,里面渲染了几个指名子router-outlet .代码如下:

App.Component.html:

<router-outlet />

App.routes.ts:

export const routes: Routes = [
  { path: '', component: SlotsView, children: [
      {
        path: '',
        outlet: 'slotA',
        component: RouterOutlet1,
      },{
        path: '',
        outlet: 'slotB',
        component: RouterOutlet2,
      }
    ]
  },
];

Slots.view.html:

This is a view with some child routes
<br>
<router-outlet name="slotA"></router-outlet>
<br>
<router-outlet name="slotB"></router-outlet>

RouterOutlet1:

  • Html:
I am Router outlet 1
  • 更少:
:host{
  background-color: #f88;
}
  • TS:
@Component({
  templateUrl: './router-outlet-1.router-outlet.html',
  styleUrls: ['./router-outlet-1.router-outlet.less'],
  encapsulation: ViewEncapsulation.Emulated,
  changeDetection: ChangeDetectionStrategy.OnPush,
  standalone: true
})
// eslint-disable-next-line  @angular-eslint/component-class-suffix
export class RouterOutlet1{
}

RouterOutlet2:

  • Html:
I am Router outlet 2
  • 更少:
:host{
  background-color: #88f;
}
  • TS:
@Component({
  templateUrl: './router-outlet-2.router-outlet.html',
  styleUrls: ['./router-outlet-2.router-outlet.less'],
  encapsulation: ViewEncapsulation.Emulated,
  changeDetection: ChangeDetectionStrategy.OnPush,
  standalone: true
})
// eslint-disable-next-line  @angular-eslint/component-class-suffix
export class RouterOutlet1{
}

请注意,两个router-outlet 之间的不同之处在于,router-outlet 1应该是略带红色(#f88),而router-outlet 2应该是蓝色(#88f).

这是实际发生的情况:

enter image description here

In DevTools I see that both host elements have the same attribute (_nghost-ng-c4243086843) enter image description here

这就是为什么相同的风格被应用到他们两个.

如果我将两个router-outlet 上的encapsulation更改为ShadowDom,则结果正确呈现:

enter image description here

问题是:

这是Angular中的一个bug,应该向开发人员报告,还是有充分的理由将Router outlet 1的样式应用于Router outlet 2?

我已经在谷歌上搜索了一下,还没有找到这样的错误报告.

我试着改变encapsulation模式.

推荐答案

更新

在判断了用户复制的Stackblitz后,下面的更改修复了问题!

  • 由于两个router-outlet 都有相同的ng-component,我们遇到了这个问题,这显然看起来像是Angular 上的错误,因为如果每个元素来自不同的插座,那么它们应该有自己的封装!

  • 要解决这个问题,我们需要直接在元素上使用host styling,以便即使属性匹配,直接应用样式也能确保 colored颜色 应用于正确的元素

-片断!-片断!

...
host: {
  ['style.backgroundColor']: '#f88',
},
...

插座1

import {
  ChangeDetectionStrategy,
  Component,
  OnInit,
  ViewEncapsulation,
} from '@angular/core';

@Component({
  templateUrl: './router-outlet1.component.html',
  styleUrls: ['./router-outlet1.component.less'],
  encapsulation: ViewEncapsulation.Emulated,
  changeDetection: ChangeDetectionStrategy.OnPush,
  host: {
    ['style.backgroundColor']: '#f88',
  },
  standalone: true,
})
export class RouterOutlet1Component implements OnInit {
  constructor() {}

  ngOnInit() {}
}

插座2

import {
  ChangeDetectionStrategy,
  Component,
  OnInit,
  ViewEncapsulation,
} from '@angular/core';

@Component({
  templateUrl: './router-outlet2.component.html',
  styleUrls: ['./router-outlet2.component.less'],
  encapsulation: ViewEncapsulation.Emulated,
  changeDetection: ChangeDetectionStrategy.OnPush,
  host: {
    ['style.backgroundColor']: '#88f',
  },
  standalone: true,
})
export class RouterOutlet2Component implements OnInit {
  constructor() {}

  ngOnInit() {}
}

Stackblitz Demo


注意:此输出来自ng-component,这甚至不是一个正确的组件,您只需重定向URL以容纳指定的router-outlet ,组件将被呈现而不是ng-component


它看起来像一个错误,但我不认为它可以复制到最新版本的Angular (17)

这是一个stackblitz,显示问题没有发生!

Stackblitz Demo

enter image description here


要解决这个问题,您可以在组件修饰器上添加一个host class,这将确保类应用到正确的主机上!

插座2

import {
  ChangeDetectionStrategy,
  Component,
  OnInit,
  ViewEncapsulation,
} from '@angular/core';

@Component({
  selector: 'app-router-outlet2',
  encapsulation: ViewEncapsulation.Emulated,
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    I am Router 插座2
  `,
  styles: `
    :host.outlet2 {
      background-color: #88f;
    }
  `,
  host: {
    '[class.outlet2]': 'true',
  },
  standalone: true,
})
export class RouterOutlet2Component implements OnInit {
  constructor() {}

  ngOnInit() {}
}

插座1

import {
  ChangeDetectionStrategy,
  Component,
  OnInit,
  ViewEncapsulation,
} from '@angular/core';

@Component({
  selector: 'app-router-outlet1',
  template: `
    I am Router 插座1
  `,
  encapsulation: ViewEncapsulation.Emulated,
  changeDetection: ChangeDetectionStrategy.OnPush,
  styles: `
    :host.outlet1 {
      background-color: #f88;
    }
  `,
  host: {
    '[class.outlet1]': 'true',
  },
  standalone: true,
})
export class RouterOutlet1Component implements OnInit {
  constructor() {}

  ngOnInit() {}
}

Stackblitz Demo

Angular相关问答推荐

在Angular 17中加载页面时打开打印对话框

以Angular 将指令事件从子组件传递到父组件

更改图表上的光标以进行zoom

如何使用ANGLING HTTP.POST并将类型更改为键入的回复?

以17角表示的自定义元素

要素存储更改根存储状态

如何确保[共享]组件是真正的哑组件?(Angular )

如何将角17中的嵌套组件与独立组件一起使用?

如何将参数传递给Angular 服务

由于ngcc操作失败,Angular扩展可能无法正常工作

使用 RXJS 进行空闲/不活动跟踪

Angular:如何设置 PrimeNG p-steps 组件中已完成步骤的样式?

在ionic 5中获取url传递的参数

如何在插值中编写条件?

如何为 Angular 2 中的渲染元素绑定事件监听器?

Angular 2从assets文件夹加载CSS背景图像

NG2-Charts 无法绑定到 datasets,因为它不是 canvas的已知属性

Angular 2表单验证重复密码

如何在项目中导入 Angular material?

包 '@angular/cli' 不是依赖项