-- first subquery to get the image urls from the blob column
with image_blob_src as (
select product_id,
APEX_UTIL.GET_BLOB_FILE_SRC(p_item_name => 'P3_PRODUCT_IMAGE',
p_v1 => product_id) img_src
from products),
-- second subquery to get the product name, category and image urls
product_image_urls as (
select PRODUCT_ID,
pc.PRODUCT_NAME,
pc.CATEGORY,
ibs.img_src image_url
from PRODUCT_WITH_CATEGORY pc join image_blob_src ibs using (product_id))
-- main query to get the category and list of image urls
-- Assume that each category has multiple images
select pu.category,
listagg(pu.image_url, '|') within group (order by pu.product_id) url_list
from product_image_urls pu
group by pu.category;
在上述的 SQL Query 中:
我們使用了 APEX_UTIL.GET_BLOB_FILE_SRC 來取得圖片的 URL。
因為一個 Card 中可能會有多張圖片,所以在 main query 中,我們使用 listagg 函數來將每個 category 的圖片 URL 串接成一個字串,並以 | 分隔。後續在 HTML Expression 中,我們會使用這個字串欄位來建立多個圖片 的URL,以便在輪播中顯示。參考 [2] 用到的技巧。
S3. 設定 Card Region 中的 Media 的 HTML 內容 及 Media 要套用的 CSS Class
// Loop through all the carousel containers
// 找出所有的輪播容器 (class 為 carousel_container 的 div)
document.querySelectorAll(".carousel_container").forEach(
function(container){
// container 為選到的輪播容器
//Declare the IntersectionObserver options
let options = {
root: container,
rootMargin: "0px",
threshold: [0.5, 1]
};
// Create the observer
// intersectionCallback 另外定義
let observer = new IntersectionObserver(intersectionCallback, options);
//Get all the images inside the container
let images = container.querySelectorAll("img");
// Loop through all images and start observe it
// 設定所要觀察的圖片
images.forEach(function(image){
observer.observe(image);
});
});
接著再設定此 Action 的 Execution 相關屬性, 啟用 Fire on Initialization. 如此,當頁面載入時,就會執行此 Action。
S5.2. 定義 Intersection Observer 的 callback function
在 Page 的 Function and Global Variable Declaration 中新增一個 JavaScript Function,做為 Intersection Observer 的 callback function。
配合上述的 html 元素結構,新增的 Intersection Observer 的 callback function 如下:
function intersectionCallback(entries) {
// Private function used to update the dots
function updateDots(container, num){
// container 為輪播容器, class 為 carousel_container 的 div
// num 為圖片的編號,放在 data-num 屬性中
// Get all the individual spans of the class carousel_dot
let dots = container.nextElementSibling.querySelectorAll(".carousel_dot");
//Loop through the dots
dots.forEach(function(dot){
// extract the data-num attribute
let dotNum = dot.getAttribute("data-num");
//Add or remove the dot's classes depending on whether it's the selected image or not
if (dotNum === num ) {
dot.classList.remove("fa-circle-o");
dot.classList.add("fa-circle");
} else {
dot.classList.add("fa-circle-o");
dot.classList.remove("fa-circle");
}
});
}
// This loops through the entries providing in the callback
entries.forEach((entry) => {
//If the image is 100% visible
if (entry.isIntersecting === true && entry.intersectionRatio === 1) {
// Get the image, image num and parent to update the dots
let image = entry.target;
let parent = image.closest(".carousel_container");
let imageNum = image.getAttribute("data-num");
updateDots(parent, imageNum);
}
});
}
完成 Resource URI Template 的建立後,我們要設定此 Resource 的 Handler, 用以處理在此 URI 下的不同的 HTTP Method 的請人求。
S4. Create a Handler for the Resource URI Template.
點選在 Resource URI Template 下方的 (B)[Create Handler]。
輸入以下資訊:
Method: GET
Source Type: Media Resource
之後,在 Source 中,設定 SQL Query:
select 'image/jpeg', product_image
from products
where product_id = :id
其中:
若 Source Type 為 Media Resource, Query 中的第一個 column 代表 MIME Type, 第二個 column 代表圖片的 binary data。
:id: 為 URI Template 中的路徑參數。
完後按 (B)[Apply Changes]。
S5. Test the RESTful Web Service.
把 RESTful Web Service 的 URL 貼到瀏覽器中,並在 URI 中加入路徑參數,應該可看到圖片。
S6. 修改 Card Region 中的 SQL Query
with image_blob_src as (
select product_id,
'/ords/project3/img/fetch/' || product_id as img_src -- Modification: generate the url for the image
from products),
product_image_urls as (
select PRODUCT_ID,
pc.PRODUCT_NAME,
pc.CATEGORY,
ibs.img_src image_url
from PRODUCT_WITH_CATEGORY pc join image_blob_src ibs using (product_id))
select pu.category,
listagg(pu.image_url, '|') within group (order by pu.product_id) url_list
from product_image_urls pu
group by pu.category;
在修改處,原本使用 APEX_UTIL.GET_BLOB_FILE_SRC 來取得圖片的 URL, 現在改為直接使用 RESTful Web Service 的 URL 加上路徑參數。
好處是,我們不再需要使用某面中的 Display Image item 來取得圖片。使用 APEX_UTIL.GET_BLOB_FILE_SRC 會相依於某個 Display Image item. 使用 RESTful Web Service 的方式可以解除這個相依性。