步驟 14:在內嵌框架中呈現元件時使用自訂樣式

在內嵌框架中呈現的元件無法直接存取 design.css 檔案。而是在元件中有一個額外步驟來取得 design.css 的 URL,然後將其新增至頁面中。您必須更新元件以反映使用者選取的樣式。

若要在元件中包含並使用 design.css 檔案,需要在 render.html 檔案中進行變更:
  1. 找出並包含 design.css 檔案的 URL

  2. 每當所選樣式類別變更時便取得其值

  3. 更新樣板以反映選取的 styleClass

  4. 在元件中反映對所選樣式類別的變更

  5. 確定內嵌框架會在樣式變更時調整大小

以下是編輯 render.html 檔案的詳細指示:

  1. 找出並包含 design.css 檔案的 URL。

    以動態方式將 design.css 檔案新增至頁面的 <head> 區段。載入之後,請設定內嵌框架的高度,因為高度可能已透過套用樣式進行更改。

    將下列程式碼新增至 viewModel 物件中:

    // Dynamically add any theme design URL to the <head> of the page
    self.loadStyleSheet = function (url) {
        var $style,
            styleSheetDeferred = new $.Deferred(),
            attempts = 100,
            numAttempts = 0,
            interval = 50,
            pollFunction = function () {
                // try to locate the style sheet
                for (var i = 0; i < document.styleSheets.length; i++) {
                    try {
                        // locate the @import sheet that has an href based on our expected URL
                        var sheet = document.styleSheets[i],
                            rules = sheet && sheet.cssRules,
                            rule = rules && rules[0];
                        // check whether style sheet has been loaded
                        if (rule && (rule.href === url)) {
                            styleSheetDeferred.resolve();
                            return;
                        }
                    } catch (e) {}
                }
                if (numAttempts < attempts) {
                    numAttempts++;
                    setTimeout(pollFunction, interval);
                } else {
                    // didn't find style sheet so complete anyway
                    styleSheetDeferred.resolve();
                }
            };
     
        // add the themeDesign stylesheet to <head>
        // use @import to avoid cross domain security issues when determining when the stylesheet is loaded
        $style = $('<style type="text/css">@import url("' + url + '")</style>');
        $style.appendTo('head');
     
        // kickoff the polling
        pollFunction();
     
        // return the promise
        return styleSheetDeferred.promise();
    };
     
    // update with the design.css from the Sites Page
    SitesSDK.getSiteProperty('themeDesign', function (data) {
        if (data && data.themeDesign && typeof data.themeDesign === 'string') {
            // load the style sheet and then set the height
            self.loadStyleSheet(data.themeDesign).done(self.setHeight);
        }
    });
  2. 每當所選樣式類別變更時便取得其值。

    建立可監測項目以追蹤 styleClass 特性的值何時變更:

    self.selectedStyleClass = ko.observable();

    請注意,擁有樣式類別後才能夠呈現。請將以下程式碼:

    self.customSettingsDataInitialized = ko.observable(false);
    self.initialized = ko.computed(function () {
        return self.customSettingsDataInitialized();
    }, self);

    改為使用以下程式碼:

    self.customSettingsDataInitialized = ko.observable(false);
    self.styleClassInitialized = ko.observable(false);
    self.initialized = ko.computed(function () {
        return self.customSettingsDataInitialized() && self.styleClassInitialized();
    }, self);

    透過新增下列程式碼取得所選樣式類別的最初值:

    self.updateStyleClass = function (styleClass) {
        self.selectedStyleClass((typeof styleClass === 'string') ? styleClass : 'hello-world-default-style'); // note that this 'hello-world' prefix is based on the app name
        self.styleClassInitialized(true);
    };
    SitesSDK.getProperty('styleClass', self.updateStyleClass);
  3. 更新樣板以反映 styleClass。請將以下程式碼:

    <p data-bind="attr: {id: 'titleId'}, text: titleText"></p>

    改為使用以下程式碼:

    <p data-bind="attr: {id: 'titleId'}, text: titleText, css: selectedStyleClass"></p>
  4. 在元件中反映對所選樣式類別的變更。請將以下程式碼:

    if (settings.property === 'customSettingsData') {
        self.updateCustomSettingsData(settings.value);
    }

    改為使用以下程式碼:

    if (settings.property === 'customSettingsData') {
        self.updateCustomSettingsData(settings.value);
    }
    if (settings.property === 'styleClass') {
        self.updateStyleClass(settings.value);
    }
  5. 確定內嵌框架會在樣式變更時調整大小。請將以下程式碼:

    // create dependencies on any observables so this handler is called whenever it changes
    var imageWidth = viewModel.imageWidth(),
          imageUrl = viewModel.imageUrl(),
          titleText = viewModel.titleText(),
          userText = viewModel.userText();

    改為使用以下程式碼:

    // create dependencies on any observables so this handler is called whenever it changes
    var imageWidth = viewModel.imageWidth(),
          imageUrl = viewModel.imageUrl(),
          titleText = viewModel.titleText(),
          userText = viewModel.userText(),
          selectedStyleClass = viewModel.selectedStyleClass();  
  6. 儲存您的檔案並將其同步至 Oracle Content Management 執行處理伺服器。

檢查步驟 14 的結果

  1. 重新整理網站中的頁面,讓網站產生器能夠取得元件的變更。

  2. 將頁面切換為「編輯」模式

  3. 將您的元件拖放到頁面中。

  4. 顯示您元件的「設定值」面板。

  5. 前往「樣式」頁籤。

  6. 切換您 design.json 檔案中定義的 GothicPlain 樣式。

    您會注意到元件切換每次選取所套用的 CSS 類別時,元件中的字型大小會有所調整以反映變更。

繼續進行步驟 15:與頁面還原和重做行為的整合