好久没用angular,记录下使用ng-zorro-antd(版本7.5.1)的坑。 最近有一个需求,是每次有新的消息时,需要弹出消息提示。消息的内容有的是要加粗的,有的是要超过长度显示省略号的,所以需要一些样式;另外要top居中展示。
Message组件
一开始使用的是Message组件。
NzMessageService.info(content, [options])
message第一个参数是消息内容,可以为字段串,也可以是templateRef。一开始就考虑到消息内容需要很多的样式代码,所以就选择了templateRef,后来就是template写好了,发现message第二个参数options只有下图的三个参数,不像notification组件是有nz-data用于给template传值的,因为需求上展示的消息内容是依赖从后端拿到的数据的,没法传值的话就放弃了templateRef。
后来到github ng-zorro-antd看了源码,看到源码实现上content的渲染代码是
<span [innerHTML]="instance.content"></span>,所以就尝试用html字符串作为content,例如this.message.info('<div style="color: red;">这是消息内容....</div>'),样式就只能内联在标签里了。
结果这样操作后,消息内容能正常展示出来了,但是样式丢失了。原因是Angular中默认将所有输入值视为不受信任,当我们通过property,attribute,样式,类绑定或插值等方式,将一个值从模板中插入到DOM中时,Angular会自帮我们清除和转义不受信任的值。也就是这里写的style被清除掉了。
为了解决样式问题,又找到了DomSanitizer类上有个bypassSecurityTrustHtml这个方法
this.message.create('', this.sanitizer.bypassSecurityTrustHtml(content));来将content绕过angular安全检查,保留完整的html。虽然实现了想要的效果。但是bypassSecurityTrustHtml是不安全的,会让应用程序面临 XSS 安全风险,最终还是放弃掉了。
notification组件
Message组件不可以,转而使用notification组件
this.notification.template(templateRef, options)
notification的template第一个参数为templateRef,options里提供了nzData用于给templateRef传值,正好符合我们预期。但是placement在当前版本只有下面四种,并没有top。导致这里只能通过修改样式让消息居中。由于这次需求里每条消息的宽度都是固定的等长的,所以这里我可以直接使用calc(50vw - 50%)来居中,如果是不固定长度的样式还需要再调整一下。
this.notification.template(
templateRef,
{
nzData: mockData,
nzStyle: {
marginLeft: 'calc(50vw - 50%)'
},
},
);