上一篇文章中我们介绍了如何使用属性和CSS去自定义组件,本篇我们将介绍另一个重要的功能,通过模板单独定义组件的UI。
所有的Microsoft Graph Toolkit组件都支持向其中添加<template>元素的方式去自定义模板。我们将以mgt-agenda为例,默认如下图的样式:
我们想要通过更改模板以展示更多信息如:
- 展示事件的日期和时间
- 点击标题可以直接跳转到日历
- 展示参与者
- 展示事件的描述信息
实现后的效果如图所示:
效果展示完了,我们来看看如何实现。
每个组件都有多个可编辑的部分,我们可以使用data-type来指定要修改哪些模板。
在本示例中,我们需要自定义3个模板:event view, no-data view和loading view。
<mgt-agenda>
<template data-type="event">
<!--
</template>
<template data-type="no-data">
<p class="noData">
There are no events found!
</p>
</template>
<template data-type="loading">
<p class="loading">
Loading...
</p>
</template>
</mgt-agenda>
为了达到我们需要的效果,我们需要写一些JavaScript函数用来供模板调用,这时我们可以利用组件中的templateContext这个属性,它可以让我们以变量、函数和事件对模板的上下文进行扩展。
const months = ["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"];
document.querySelector('mgt-agenda').templateContext = {
openWebLink: (e, context, root) => {
window.open(context.event.webLink, '_blank');
},
getDate: (dateString) => {
let dateObject = new Date(dateString);
return dateObject.setHours(0, 0, 0, 0);
},
getTime: (dateString) => {
let dateObject = new Date(dateString);
return dateObject.getHours().toString().padEnd(2, '0')
+ ':' + dateObject.getMinutes().toString().padEnd(2, '0');
},
formatDate: (date) => {
let dateObject = new Date(date);
return dateObject.getDate()
+ "/" + months[dateObject.getMonth()]
+ "/" + dateObject.getFullYear();
},
getTextFromHTML(htmlString) {
var doc = (new DOMParser()).parseFromString(htmlString, "text/html");
return doc.body.innerText;
}
}
现在我们有了格式化日期的函数getDate、getTime和formatDate,打开访问日历链接的函数openWebLink和一个从HTML字符串中获取文本的函数getTextFromHTML。
引用想要显示在模板中的数据,可以使用数据绑定表达式如{{event.subject}}这种格式。可以使用data-props属性去添加事件监听器或在模板中直接设置属性,事件监听器可以通过"@eventName"这种格式添加如@click:openWebLink。
<template data-type="event">
<div class="event">
...
<div class="event-title" data-props="{{@click: openWebLink}}">
{{ event.subject }} @ {{event.location.displayName}}
</div>
...
<div class="event-description" data-props="{{innerHTML: event.body.content}}" /> ...
</div>
</template>
本例中第一个div会展示事件的标题和显示名,并附加了点击事件。第二个div会展示事件的主体信息。
我们还可以使用data-if和data-else属性来设置不同条件下展示不同的内容:
<template data-type="event">
<div class="event">
...
<div data-if="getDate(event.start.dateTime) == getDate(event.end.dateTime)"
class="event-subTitle">
{{formatDate(event.start.dateTime)}}
from {{getTime(event.start.dateTime)}}
to {{getTime(event.end.dateTime)}}
</div>
<div data-else class="event-subTitle">
{{formatDate(event.start.dateTime)}} ({{getTime(event.start.dateTime)}})
-
{{formatDate(event.end.dateTime)}} ({{getTime(event.end.dateTime)}})
</div>
...
</div>
</template>
最后要实现的模板部分是参与者的信息展示:
<template data-type="event">
<div class="event">
...
<div class="event-attendees">
<mgt-person data-for="attendee in event.attendees"
person-query="{{ attendee.emailAddress.name }}"
person-card="hover" />
</div>
...
</div>
</template>
这里我们使用了mgt-person组件,data-for属性表示要在哪个集合中循环遍历。
模板的使用方法就介绍到这,更多内容请参考Microsoft Docs文档,附上本篇介绍内容的全部源码供参考。