ส่วนเสริมแบบการ์ดส่วนใหญ่สร้างขึ้นโดยใช้การ์ดหลายใบซึ่งแสดงถึง "หน้า" ต่างๆ ของอินเทอร์เฟซส่วนเสริม คุณควรใช้การนำทางที่เรียบง่ายและเป็นธรรมชาติระหว่างการ์ดในส่วนเสริมเพื่อให้ผู้ใช้ได้รับประสบการณ์ที่มีประสิทธิภาพ
เดิมทีในส่วนเสริมของ Gmail การเปลี่ยนระหว่างการ์ดต่างๆ ของ UI จะ ได้รับการจัดการโดยการพุชและป๊อปการ์ดเข้าและออกจากกองการ์ดเดียว โดย Gmail จะแสดงการ์ดบนสุดของกอง

ส่วนเสริมของ Google Workspace ขอแนะนำ
หน้าแรกและ
การ์ดที่ไม่ขึ้นอยู่กับบริบท ส่วนเสริมของ Google Workspace มีกองการ์ดภายในสำหรับแต่ละการ์ด
เพื่อรองรับการ์ดตามบริบทและที่ไม่ใช่ตามบริบท เมื่อเปิดส่วนเสริมในโฮสต์ homepageTrigger ที่เกี่ยวข้องจะเริ่มทำงานเพื่อสร้างการ์ดหน้าแรกแรกในกอง (การ์ด "หน้าแรก" สีน้ำเงินเข้มในไดอะแกรมด้านล่าง)
หากไม่ได้กำหนด homepageTrigger ระบบจะสร้าง แสดง
และพุชการ์ดเริ่มต้นไปยังกองที่ไม่ใช่บริบท การ์ดแรกนี้คือการ์ดรูท
ส่วนเสริมของคุณสามารถสร้างการ์ดที่ไม่ใช่บริบทเพิ่มเติมและส่งไปยัง กองซ้อน (การ์ด "ที่ส่ง" สีน้ำเงินในไดอะแกรม) ขณะที่ผู้ใช้ไปยังส่วนต่างๆ ของส่วนเสริม UI ของส่วนเสริมจะแสดงการ์ดบนสุดในกอง ดังนั้นการพุชการ์ดใหม่ ไปยังกองจะเปลี่ยนการแสดงผล และการป๊อปการ์ดออกจากกองจะเปลี่ยน การแสดงผลกลับไปเป็นการ์ดก่อนหน้า
หากส่วนเสริมมีทริกเกอร์ตามบริบทที่กำหนดไว้
เมื่อผู้ใช้เข้าสู่บริบทนั้น ทริกเกอร์จะเริ่มทำงาน ฟังก์ชันทริกเกอร์
สร้างการ์ดตามบริบท แต่การแสดง UI จะอัปเดตตาม
DisplayStyle
ของการ์ดใหม่
- หาก
DisplayStyleเป็นREPLACE(ค่าเริ่มต้น) การ์ดตามบริบท (การ์ด "ตามบริบท" สีส้มเข้ม ในไดอะแกรม) จะแทนที่การ์ดที่แสดงอยู่ ซึ่งจะเริ่มสแต็กการ์ดตามบริบทใหม่ที่ด้านบน ของสแต็กการ์ดที่ไม่ใช่ตามบริบท และการ์ดตามบริบทนี้จะเป็นการ์ดรูท ของสแต็กตามบริบท - หาก
DisplayStyleเป็นPEEKUI จะสร้างส่วนหัวแบบแอบดูแทน ซึ่งจะปรากฏที่ ด้านล่างของแถบด้านข้างของส่วนเสริม โดยซ้อนทับการ์ดปัจจุบัน ส่วนหัวของการ์ดที่ซ่อนอยู่ จะแสดงชื่อของการ์ดใหม่และปุ่มควบคุมสำหรับผู้ใช้ที่ช่วยให้ ผู้ใช้ตัดสินใจได้ว่าจะดูการ์ดใหม่หรือไม่ หากคลิกปุ่มดู การ์ดจะแทนที่การ์ดปัจจุบัน (ตามที่อธิบายไว้ข้างต้นด้วยREPLACE)
คุณสามารถสร้างการ์ดตามบริบทเพิ่มเติมและ ส่งไปยังกองซ้อน (การ์ดที่ "ส่ง" สีเหลืองในไดอะแกรม) การอัปเดต กองการ์ดจะเปลี่ยน UI ของส่วนเสริมเพื่อแสดงการ์ดที่อยู่ด้านบนสุด หากผู้ใช้ ออกจากบริบท ระบบจะนำการ์ดตามบริบทในกองออกและอัปเดตการแสดงผล เป็นการ์ดที่ไม่ใช่ตามบริบทที่อยู่ด้านบนสุดหรือหน้าแรก
หากผู้ใช้ป้อนบริบทที่ส่วนเสริมของคุณไม่ได้กำหนดทริกเกอร์ตามบริบทไว้ ระบบจะไม่สร้างการ์ดใหม่และจะแสดงการ์ดปัจจุบันต่อไป
การดำเนินการ Navigation
ที่อธิบายไว้ด้านล่างจะมีผลกับการ์ดจากบริบทเดียวกันเท่านั้น เช่น
popToRoot()
จากการ์ดตามบริบทจะแสดงการ์ดตามบริบทอื่นๆ ทั้งหมดเท่านั้น
และจะไม่มีผลต่อการ์ดในหน้าแรก
ในทางตรงกันข้าม ปุ่มจะพร้อมให้ผู้ใช้ไปยังการ์ดที่ไม่ใช่บริบทจาก การ์ดตามบริบทเสมอ
วิธีการนำทาง
คุณสร้างการเปลี่ยนภาพระหว่างการ์ดได้โดยการเพิ่มหรือนำการ์ดออกจากกองการ์ด คลาส Navigation
มีฟังก์ชันสำหรับพุชและป๊อปการ์ดออกจากกอง หากต้องการสร้างการนำทางด้วยการ์ดที่มีประสิทธิภาพ ให้กำหนดค่าวิดเจ็ตให้ใช้การดำเนินการนำทาง คุณสามารถพุชหรือป๊อป
การ์ดหลายใบพร้อมกันได้ แต่จะนำการ์ดหน้าแรกเริ่มต้น
ที่พุชลงในกองเป็นรายการแรกเมื่อส่วนเสริมเริ่มทำงานออกไม่ได้
หากต้องการไปยังการ์ดใหม่เพื่อตอบสนองต่อการโต้ตอบของผู้ใช้กับวิดเจ็ต ให้ทำตามขั้นตอนต่อไปนี้
- สร้างออบเจ็กต์
Actionและเชื่อมโยงกับ ฟังก์ชันเรียกกลับ ที่คุณกำหนด - เรียกใช้ฟังก์ชันตัวแฮนเดิลวิดเจ็ตที่เหมาะสมของวิดเจ็ต
เพื่อตั้งค่า
Actionในวิดเจ็ตนั้น - ใช้ฟังก์ชันเรียกกลับที่นำทาง ฟังก์ชันนี้
ได้รับออบเจ็กต์เหตุการณ์การกระทํา
เป็นอาร์กิวเมนต์ และต้องทําสิ่งต่อไปนี้
- สร้างออบเจ็กต์
Navigationเพื่อกำหนดการเปลี่ยนแปลงการ์ดNavigationออบเจ็กต์เดียวสามารถ มีขั้นตอนการนำทางหลายขั้นตอน ซึ่งจะดำเนินการตามลำดับ ที่เพิ่มลงในออบเจ็กต์ - สร้างออบเจ็กต์
ActionResponseโดยใช้คลาสActionResponseBuilderและออบเจ็กต์Navigation - ส่งคืน
ActionResponseที่สร้างขึ้น
- สร้างออบเจ็กต์
เมื่อสร้างตัวควบคุมการนำทาง คุณจะใช้ฟังก์ชันออบเจ็กต์ต่อไปนี้
Navigation
| ฟังก์ชัน | คำอธิบาย |
|---|---|
Navigation.pushCard(Card) |
ส่งการ์ดไปยังกองปัจจุบัน ซึ่งต้องสร้างการ์ดให้เสร็จสมบูรณ์ก่อน |
Navigation.popCard() |
นำไพ่ 1 ใบออกจากด้านบนสุดของกอง เทียบเท่ากับการคลิกลูกศรกลับในแถวส่วนหัวของส่วนเสริม แต่จะไม่นำการ์ดรูทออก |
Navigation.popToRoot() |
นำการ์ดทั้งหมดออกจากกอง ยกเว้นการ์ดรูท ซึ่งเป็นการรีเซ็ตกองการ์ด |
Navigation.popToNamedCard(String) |
แสดงการ์ดจากกองจนกว่าจะถึงการ์ดที่มีชื่อที่ระบุหรือการ์ดรูทของกอง คุณกำหนดชื่อให้กับการ์ดได้โดยใช้ฟังก์ชัน CardBuilder.setName(String) |
Navigation.updateCard(Card) |
แทนที่การ์ดปัจจุบันโดยตรง ซึ่งจะรีเฟรชการแสดงผลในการ์ดใน UI |
แนวทางปฏิบัติแนะนำในการนำทาง
หากการโต้ตอบหรือเหตุการณ์ของผู้ใช้ควรทําให้การ์ดได้รับการแสดงผลซ้ำในบริบทเดียวกัน
ให้ใช้วิธีการ
Navigation.pushCard()
Navigation.popCard()
และ Navigation.updateCard()
เพื่อแทนที่การ์ดที่มีอยู่ หากการโต้ตอบหรือเหตุการณ์ของผู้ใช้ควร
ส่งผลให้มีการแสดงผลการ์ดอีกครั้งในบริบทอื่น ให้ใช้
ActionResponseBuilder.setStateChanged()
เพื่อบังคับให้ส่วนเสริมทำงานอีกครั้งในบริบทเหล่านั้น
ตัวอย่างการนำทางมีดังนี้
- หากการโต้ตอบหรือเหตุการณ์เปลี่ยนสถานะของบัตรปัจจุบัน (เช่น
การเพิ่มงานลงในรายการงาน) ให้ใช้
updateCard() - หากการโต้ตอบหรือเหตุการณ์ให้รายละเอียดเพิ่มเติมหรือแจ้งให้ผู้ใช้
ดำเนินการเพิ่มเติม (เช่น การคลิกชื่อรายการเพื่อดูรายละเอียดเพิ่มเติม หรือ
การกดปุ่มเพื่อสร้างกิจกรรมในปฏิทินใหม่) ให้ใช้
pushCard()เพื่อแสดงหน้าใหม่ในขณะที่อนุญาตให้ผู้ใช้ออกจากหน้าใหม่โดยใช้ ปุ่มย้อนกลับ - หากการโต้ตอบหรือเหตุการณ์อัปเดตสถานะในการ์ดก่อนหน้า (เช่น
การอัปเดตชื่อของรายการจากมุมมองรายละเอียด) ให้ใช้สิ่งต่อไปนี้
popCard()popCard()pushCard(previous)และpushCard(current)เพื่ออัปเดตการ์ดก่อนหน้าและการ์ดปัจจุบัน
การรีเฟรชการ์ด
ส่วนเสริม Google Workspace ช่วยให้ผู้ใช้สามารถ รีเฟรชการ์ดได้โดยการเรียกใช้ฟังก์ชันทริกเกอร์ Apps Script ที่ลงทะเบียนไว้ใน ไฟล์ Manifest อีกครั้ง ผู้ใช้จะทริกเกอร์การรีเฟรชนี้ผ่านรายการเมนูส่วนเสริมได้โดยทำดังนี้
ระบบจะเพิ่มการดำเนินการนี้ลงในการ์ดที่สร้างโดย homepageTrigger หรือฟังก์ชันทริกเกอร์ contextualTrigger โดยอัตโนมัติตามที่ระบุไว้ในไฟล์ Manifest ของส่วนเสริม
("ราก" ของกองการ์ดตามบริบทและไม่ตามบริบท)
ส่งคืนบัตรหลายใบ
ฟังก์ชันทริกเกอร์หน้าแรกหรือบริบทใช้เพื่อสร้างและแสดงออบเจ็กต์ Card รายการเดียวหรืออาร์เรย์ของออบเจ็กต์ Card ที่ UI ของแอปพลิเคชันแสดง
หากมีบัตรเพียงใบเดียว ระบบจะเพิ่มบัตรนั้นลงในกองบัตรที่ไม่ใช่บริบทหรือกองบัตรบริบท เป็นบัตรรูท และ UI ของแอปพลิเคชันโฮสต์จะแสดงบัตรนั้น
หากอาร์เรย์ที่ส่งคืนมีออบเจ็กต์ที่สร้างไว้ล่วงหน้ามากกว่า 1 รายการ Card
แอปพลิเคชันโฮสต์จะแสดงการ์ดใหม่แทน ซึ่งมีการ์ดส่วนหัวของแต่ละการ์ด เมื่อผู้ใช้คลิกส่วนหัวใดส่วนหัวหนึ่ง UI
จะแสดงการ์ดที่เกี่ยวข้อง
เมื่อผู้ใช้เลือกการ์ดจากรายการ ระบบจะส่งการ์ดนั้นไปยัง กองปัจจุบันและแอปพลิเคชันโฮสต์จะแสดงการ์ด ปุ่ม จะนำผู้ใช้กลับไปที่ รายการส่วนหัวของการ์ด
การจัดเรียงการ์ดแบบ "แบน" นี้จะใช้ได้ดีหากส่วนเสริมไม่จำเป็นต้องมีการเปลี่ยนผ่านระหว่างการ์ดที่คุณสร้าง อย่างไรก็ตาม ในกรณีส่วนใหญ่ วิธีที่แนะนำคือการกำหนดการเปลี่ยนการ์ดโดยตรง และให้ฟังก์ชันทริกเกอร์ตามบริบทของหน้าแรกส่งคืนออบเจ็กต์การ์ดรายการเดียว
ตัวอย่าง
ตัวอย่างต่อไปนี้แสดงวิธีสร้างการ์ดหลายใบที่มีปุ่มนำทางซึ่งจะข้ามไปมาระหว่างการ์ด คุณสามารถเพิ่มการ์ดเหล่านี้ลงในสแต็ก
ตามบริบทหรือไม่ตามบริบทก็ได้โดยการพุชการ์ดที่ createNavigationCard() ส่งคืน
ในหรือนอกบริบทใดบริบทหนึ่ง
/**
* Create the top-level card, with buttons leading to each of three
* 'children' cards, as well as buttons to backtrack and return to the
* root card of the stack.
* @return {Card}
*/
function createNavigationCard() {
// Create a button set with actions to navigate to 3 different
// 'children' cards.
var buttonSet = CardService.newButtonSet();
for(var i = 1; i <= 3; i++) {
buttonSet.addButton(createToCardButton(i));
}
// Build the card with all the buttons (two rows)
var card = CardService.newCardBuilder()
.setHeader(CardService.newCardHeader().setTitle('Navigation'))
.addSection(CardService.newCardSection()
.addWidget(buttonSet)
.addWidget(buildPreviousAndRootButtonSet()));
return card.build();
}
/**
* Create a button that navigates to the specified child card.
* @return {TextButton}
*/
function createToCardButton(id) {
var action = CardService.newAction()
.setFunctionName('gotoChildCard')
.setParameters({'id': id.toString()});
var button = CardService.newTextButton()
.setText('Card ' + id)
.setOnClickAction(action);
return button;
}
/**
* Create a ButtonSet with two buttons: one that backtracks to the
* last card and another that returns to the original (root) card.
* @return {ButtonSet}
*/
function buildPreviousAndRootButtonSet() {
var previousButton = CardService.newTextButton()
.setText('Back')
.setOnClickAction(CardService.newAction()
.setFunctionName('gotoPreviousCard'));
var toRootButton = CardService.newTextButton()
.setText('To Root')
.setOnClickAction(CardService.newAction()
.setFunctionName('gotoRootCard'));
// Return a new ButtonSet containing these two buttons.
return CardService.newButtonSet()
.addButton(previousButton)
.addButton(toRootButton);
}
/**
* Create a child card, with buttons leading to each of the other
* child cards, and then navigate to it.
* @param {Object} e object containing the id of the card to build.
* @return {ActionResponse}
*/
function gotoChildCard(e) {
var id = parseInt(e.parameters.id); // Current card ID
var id2 = (id==3) ? 1 : id + 1; // 2nd card ID
var id3 = (id==1) ? 3 : id - 1; // 3rd card ID
var title = 'CARD ' + id;
// Create buttons that go to the other two child cards.
var buttonSet = CardService.newButtonSet()
.addButton(createToCardButton(id2))
.addButton(createToCardButton(id3));
// Build the child card.
var card = CardService.newCardBuilder()
.setHeader(CardService.newCardHeader().setTitle(title))
.addSection(CardService.newCardSection()
.addWidget(buttonSet)
.addWidget(buildPreviousAndRootButtonSet()))
.build();
// Create a Navigation object to push the card onto the stack.
// Return a built ActionResponse that uses the navigation object.
var nav = CardService.newNavigation().pushCard(card);
return CardService.newActionResponseBuilder()
.setNavigation(nav)
.build();
}
/**
* Pop a card from the stack.
* @return {ActionResponse}
*/
function gotoPreviousCard() {
var nav = CardService.newNavigation().popCard();
return CardService.newActionResponseBuilder()
.setNavigation(nav)
.build();
}
/**
* Return to the initial add-on card.
* @return {ActionResponse}
*/
function gotoRootCard() {
var nav = CardService.newNavigation().popToRoot();
return CardService.newActionResponseBuilder()
.setNavigation(nav)
.build();
}