处理 Oracle JET Web 应用程序中的选择事件

简介

可以使用 Oracle JET Web 应用程序 viewModel 中的 Oracle JavaScript Extension Toolkit (Oracle JET) API 创建响应 Oracle JET 列表视图组件 selected 属性更改监听程序的事件处理程序。当用户选择或取消选择列表中的项时,更改监听程序将触发事件处理程序。可以使用事件处理程序填充 Oracle JET 数据提供程序,也可以将数据提供程序绑定到观察视图组件可以使用的表。事件处理程序还可以设置 Oracle JET If Binding 组件用于有条件地在视图中呈现其嵌套 HTML 元素的布尔变量。如果主列表的 Oracle JET 列表视图组件的 selected 属性不为空,则该变量将设置为 true,并且视图会呈现数据库详细信息列表。如果 selected 属性由于取消选择事件而为空,则该变量将设置为“假”,并且视图会在视图中呈现一个没有数据连接详细信息列表的容器。

目标

在本教程中,您将更新 Oracle JET Web 应用程序的用户界面,以便显示主从数据。您将学习如何使用 Oracle JET 属性更改监听程序创建 JavaScript 事件处理程序。您还将学习如何使用 Oracle JET If Binding 组件有条件地显示用于处理列表选择的明细列表。

先决条件

任务 1:在视图中设置选择行为

更新视图以自定义列表视图组件,以处理“活动”列表和“活动项目”列表中的行选择。Oracle JET 列表视图组件定义组件使用用户行选择的数据项填充的 first-selected-item 属性,可以使用双向绑定读入可观察项。使用组件的 on-selection-changed 属性通过绑定您在 viewModel 中定义的事件监听程序来捕获和处理列表选择 / 取消选择事件。

  1. 导航到 JET_Web_Application/src/ts/views 目录并在编辑器中打开 dashboard.html 文件。

  2. 在“活动”标题下方,找到 oj-list-view 自定义 HTML 元素(其中 id="activitiesList"),然后在 gridlines.item 属性后添加选择行为属性。

       
    <h3 id="activitiesHeader">Activities</h3>
       <oj-list-view id="activitiesList" class="item-display" aria-labelledby="activitiesHeader"
         data="[[activityDataProvider]]" gridlines.item="visible" selection-mode="single" selected="{{selectedActivity}}"
         on-first-selected-item-changed="[[selectedActivityChanged]]" first-selected-item="{{firstSelectedActivity}}"
         scroll-policy="loadMoreOnScroll" scroll-policy-options.fetch-size="5">
         <template slot="itemTemplate">
    . . .
       
    
  3. 在“活动项”标题下方,找到 oj-list-view 自定义 HTML 元素(其中 id="itemsList"),然后在 gridlines.item 属性后添加选择行为属性。

       
    <h3 id="itemsListHeader">Activity Items</h3>
         <oj-list-view id="itemsList" class="item-display" data="[[itemsDataProvider]]" aria-labelledby="itemsListHeader"
           gridlines.item="visible" selection-mode="single" selected="{{selectedItem}}"
           on-first-selected-item-changed="[[selectedItemChanged]]" first-selected-item="{{firstSelectedItem}}"
           scroll-policy="loadMoreOnScroll" scroll-policy-options.fetch-size="5">
           <template slot="itemTemplate">
    . . .
       
    
  4. 保存 dashboard.html 文件。

    您的文件应类似于 event-task1-dashboard-html.txt

任务 2:在 ViewModel 中创建事件处理程序

更新 viewModel,为列表视图组件添加事件处理程序,以响应“活动”列表和“活动项”列表中的选择。Oracle JET 列表视图组件定义 selected 属性,Oracle JET 列表视图 API 在其中定义属性更改监听程序。当用户进行列表选择并且 selected 属性的值发生更改时,您的事件处理程序将设置 selectedActivityselectedItem 可观察。

  1. 导航到 JET_Web_Application/src/ts/viewModels 目录并在编辑器中打开 dashboard.ts 文件。

  2. pieSeriesValue 可观测定义下方,在 constructor() 之前,为“活动列表”选择和“活动项”列表选择添加可观察项。

    class DashboardViewModel {
       . . . 
       pieSeriesValue: ko.ObservableArray;
       // Observables for Activities
       selectedActivity = new ObservableKeySet();
       activitySelected = ko.observable(false);  // Controls display of Activity Items
       firstSelectedActivity = ko.observable();
       selectedActivityIds = ko.observable();
    
       // Observables for Activity Items
       itemSelected = ko.observable(false);
       selectedItem = ko.observable();
       firstSelectedItem = ko.observable();
    
       constructor() {
       . . .
    
    
  3. dashboard.ts 文件的顶部,从 ojs/ojknockout-keyset 模块和 ojs/ojlistview 模块中的 ojListView 类导入 ObservableKeySet 类。

    import * as ko from "knockout";
    . . . 
    import "ojs/ojavatar";
    import { ObservableKeySet } from "ojs/ojknockout-keyset";
    import { ojListView } from "ojs/ojlistview";
    
  4. DashboardViewModel 类之前,添加 ActivityItems 类型别名。

    . . . 
    type ActivityItems = {
       id: number;
       name: string;
       items: Array<Item>;
       short_desc: string;
       image: string;
    };
    
    class DashboardViewModel {
    . . .
    
  5. DashboardViewModelconstructor() 方法声明之后,添加具有测试条件的 selectedActivityChanged 事件处理程序以处理选择和取消选择事件。

    } // End of constructor function
    
    selectedActivityChanged = (event: ojListView.firstSelectedItemChanged<ActivityItems["id"], ActivityItems>) => {
       /**
       *  If no items are selected then the firstSelectedItem property  returns an object 
       *  with both key and data properties set to null.
       */
       let itemContext = event.detail.value.data;
    
       if (itemContext != null) {    
          // If selection, populate and display list
    
       } else {
             // If deselection, hide list          
       }
    };
    

    在后续步骤中实施此事件处理程序。

  6. selectedActivityChanged 事件处理程序的 if 语句中,使用 itemsArray 变量填充可观察的 itemsDataProvider,然后针对选择事件将 activitySelecteditemSelected 选择状态可观察文件设置为 true

    
    selectedActivityChanged = (event: ojListView.firstSelectedItemChanged<ActivityItems["id"], ActivityItems>) => {
       /**
        *  If no items are selected, then this property firstSelectedItem 
        *  will return an object with both key and data properties set to null.
       */
       let itemContext = event.detail.value.data;
    
       if (itemContext != null) {    
          // If selection, populate and display list
          // Hide currently-selected activity item
          this.activitySelected(false);
    
          let itemsArray = itemContext.items;
          this.itemsDataProvider.data = itemsArray;
          // Set List View properties
          this.activitySelected(true);
          this.itemSelected(false);
          this.selectedItem();
          this.itemData();
    
       } else {
             // If deselection, hide list
       }
    };
    
    
  7. selectedActivityChanged 事件处理程序的 else 语句中,将取消选择事件的 activitySelecteditemSelected 选择状态可观察文件设置为 false

    
    selectedActivityChanged = (event: ojListView.firstSelectedItemChanged<ActivityItems["id"], ActivityItems>) => {
       /**
        *  If no items are selected then this property firstSelectedItem will return an 
        *  object with both key and data properties set to null.
       */
    
       let itemContext = event.detail.value.data;
    
       if (itemContext != null) {    
          . . .
       } 
    
       else {
          // If deselection, hide list
          this.activitySelected(false);
          this.itemSelected(false);
       }
    };
    
    
  8. selectedActivityChanged 事件处理程序之后,添加具有测试条件的 selectedItemChanged 事件处理程序以处理选择和取消选择事件。

    
    selectedActivityChanged = (event: ojListView.firstSelectedItemChanged<ActivityItems["id"], ActivityItems>) => {
       . . .
    };
    
    /**
    * Handle selection from Activity Items list
    */
    selectedItemChanged = (event: ojListView.firstSelectedItemChanged<Item["id"], Item>) => {
    
       let isClicked = event.detail.value.data;
    
       if (isClicked != null) {
    
           // If selection, populate and display list
       }
       else {
       // If deselection, hide list
       }
    };
    

    在后续步骤中实施此事件处理程序。

  9. selectedItemChanged 事件处理程序的 if 语句中,填充可观察的 itemData,使用 pieSeries 数组变量填充可观察的 pieSeriesValue,然后针对选择事件将可观察的 itemSelected 选择状态设置为 true

    selectedItemChanged = (event: ojListView.firstSelectedItemChanged<Item["id"], Item>) => {
    
       let isClicked = event.detail.value.data;
    
       if (isClicked != null) {
    
          // If selection, populate and display list
          this.itemData(event.detail.value.data);
    
          // Create variable and get attributes of the items list to set pie chart values
          let pieSeries = [
          { name: "Quantity in Stock", items: [this.itemData().quantity_instock] },
          { name: "Quantity Shipped", items: [this.itemData().quantity_shipped] }
          ];
          // Update the pie chart with the data
          this.pieSeriesValue(pieSeries);
    
          this.itemSelected(true);
    
       }
       else {
       // If deselection, hide list
    
       }
    };
    
  10. selectedItemChanged 事件处理程序的 else 语句中,将取消选择事件的 itemSelected 选择状态设置为可观察到 false

    selectedItemChanged = (event: ojListView.firstSelectedItemChanged<Item["id"], Item>) => {
    
       if (isClicked != null) {
       . . . 
       }
       else {
       // If deselection, hide list
       this.itemSelected(false);        
       }
    };
    
  11. 保存 dashboard.ts 文件。

    您的文件应类似于 final-event-dashboard-ts.txt

任务 3:在视图中条件化列表呈现

使用 Oracle JET If Binding 组件更新视图,以有条件地呈现明细列表。Oracle JET If Binding 组件在其 test 属性上使用布尔变量。在一个“如果绑定”组件中,嵌套“活动项”容器,并在另一个“如果绑定”组件中嵌套“项详细信息”容器。然后使用 If Binding 组件测试可观察文件 activitySelecteditemSelected 的状态。如果测试条件为 true,则 If Binding 组件的嵌套内容会呈现。如果可观察文件为 true,则显示数据库列表,如列表事件处理程序所设置的。使用另一个 If 绑定组件测试可观察值为 false,然后显示包含指示用户进行列表选择的消息的容器。

  1. 导航到 JET_Web_Application/src/ts/views 目录并在编辑器中打开 dashboard.html 文件。

  2. 找到 div 元素,其中 id="parentContainer2"。在上面添加 oj-bind-if 自定义 HTML 元素的开始标记,test 属性设置为可观察的 activitySelected 的状态。

    . . .
       </oj-list-view>
    </div>
    <oj-bind-if test="[[activitySelected()]]">
    <div id="parentContainer2" class="oj-flex oj-flex-item oj-panel oj-bg-danger-30 oj-lg-padding-6x oj-md-8 oj-sm-12">
       <div id="activityItemsContainer" class="oj-flex-item oj-md-6 oj-sm-12">
       <h3 id="itemsListHeader">Activity Items</h3>
    . . .
    

    当用户从“活动”列表中选择活动时,viewModel“已更改活动”事件处理程序会将可观察的 activitySelected 的值设置为 true。在这种情况下,满足 oj-bind-if 测试条件,应用程序会为活动选择呈现“活动项”容器。可观测属性上的 () 表示法是 Knockout 函数约定,用于获取可观察对象的值,而不是获取可观察对象的实例。

  3. 找到 div 元素,其中 id="itemDetailsContainer",在上面添加 oj-bind-if 定制 HTML 元素的开始标记,test 属性设置为可观察的 itemSelected 的状态。

    . . .
       </oj-list-view>
    </div>
    <oj-bind-if test="[[itemSelected()]]">
    <div id="itemDetailsContainer" class="oj-flex-item oj-panel oj-bg-neutral-30 oj-md-6 oj-sm-12">
       <h3>Item Details</h3>
    . . .     
    

    当用户从“活动项目”列表中选择项目时,viewModel“已更改项目”事件处理程序会将可观察的 itemSelected 设置为 true。在这种情况下,满足 oj-bind-if 测试条件,应用程序会为活动项选择呈现“项详细信息”容器。

  4. dashboard.html 文件的底部,向上计数两个结束 </div> 标记,然后添加结束 </oj-bind-if> 标记以匹配打开的 <oj-bind-if test ="[[activitySelected()]]"> 标记。再计算一个结束 </div> 标记,然后为打开的 <oj-bind-if test ="[[itemSelected()]]"> 标记添加结束 </oj-bind-if> 标记。

    . . . 
                </oj-chart>
                </div>
             </div>
          </oj-bind-if>
          </div>
       </oj-bind-if>
       </div>
    </div>
    
  5. 在您添加的关闭 </oj-bind-if> 标记(最接近文件末尾)下方,插入 oj-bind-if test="[[!activitySelected()]]" 自定义 HTML 元素,其中包含带有 Oracle JET oj-flex-item oj-sm-6 弹性布局帮助程序类的 div 元素。

    . . . 
                </oj-bind-if>
             </div>
          </oj-bind-if>
          <oj-bind-if test="[[!activitySelected()]]">
             <div class="oj-flex-item oj-sm-6">
             <p>Select an Activity to see Items</p>
             </div>
          </oj-bind-if>
       </div>
    </div>
    

    Oracle JET oj-sm-6 帮助程序类指定 Select an Activity to see Items 标题的容器占用六个小屏和大屏幕大小的容器列。

    在用户选择活动之前,可观察的 activitySelected 值为 false。同样,如果用户按 Ctrl 键并单击已选择的活动,则 viewModel 会将此事件视为取消选择,并且“活动更改”事件处理程序会将可观察的 activitySelected 设置为 false。在这两种情况下,oj-bind-if 测试条件均由布尔 false 条件满足,应用程序会呈现 Select an Activity to see Items 标题。

  6. 在文件中的第一个结束 </oj-bind-if> 标记下方,添加包含 div 元素的 oj-bind-if test ="[[!itemSelected()]]" 自定义 HTML 元素以及 Oracle JET oj-flex-item oj-sm-12 oj-md-6 flex 布局帮助程序类。

    . . .
                      </oj-chart>
                   </div>
                </div>
             </oj-bind-if>
             <oj-bind-if test="[[!itemSelected()]]">
                <div class="oj-flex-item oj-sm-12 oj-md-6">
                   <p>Select an Item to see details</p>
                </div>
             </oj-bind-if>
             </div>
          </oj-bind-if>
          <oj-bind-if test="[[!activitySelected()]]">
             <div class="oj-flex-item oj-sm-6">
             <p>Select an Activity to see Items</p>
             </div>
          </oj-bind-if>
       </div>
    </div>
    

    Oracle JET oj-sm-12oj-md-6 帮助类指定用于查看详细信息标题的 Select an Item 容器占用六个用于中较大屏幕大小的容器列,或者占用十二个用于小屏幕大小的容器列。

    在用户选择活动项之前,可观察的 itemSelected 的值是 false。同样,如果用户按 Ctrl 键并单击已选择的活动项,则 viewModel 会将此事件视为取消选择,并且“项更改”事件处理程序会将可观察的 itemSelected 设置为 false。在这两种情况下,oj-bind-if 测试条件均由布尔 false 条件满足,应用程序会呈现 Select an Item to see details 标题。

  7. 保存 dashboard.html 文件。

    您的文件应类似于 final-event-dashboard-html.txt

任务 4:测试主列表和明细列表

  1. 在终端窗口中,转到 JET_Web_Application 目录并运行应用程序。

    $ ojet serve
    
  2. 在 Web 浏览器中,单击应用程序中的棒球活动。

    活动列表选择将触发 selectedActivityChanged 事件处理程序。为所选活动呈现活动项容器。

    为棒球活动呈现的活动项目

    插图 master_detail_list.png 的说明

  3. 活动项列表中,单击 SureCatch 棒球曲线

    活动项列表选择将触发 selectedItemChanged 事件处理程序。应用程序为选定项呈现项详细信息容器。

    为棒球活动呈现的活动项目

    插图 master_detail_item.png 的说明

  4. Activity Items(活动项)列表中,按 Ctrl 并单击 SureCatch Baseball Glove 取消选择它。

    活动项列表取消选择将触发 selectedItemChanged 事件处理程序。项目详细信息容器处于隐藏状态。

    取消选择 SureCatch 棒球手枪将隐藏项目详细信息

    插图 master_detail_list.png 的说明

  5. 调整浏览器的大小,或者按 Ctrl+Shift+I 启动 Chrome DevTools 并从屏幕大小仿真器中选择较小的屏幕大小,例如 Pixel 5

    容器根据屏幕大小进行排列。

    容器重新排列以适合小屏幕大小

    插图 resized_master_detail_list.png 的说明

  6. 关闭显示正在运行的 Web 应用程序的浏览器窗口或选项卡。

  7. 在终端窗口中,按 Ctrl+C,如果出现提示,输入 y 以退出 Oracle JET 工具批处理作业。

任务 5:(可选)从恢复的应用程序运行 Web 应用程序

如果要从提供的代码运行完成的 Oracle JET Web 应用程序,可以从下载的归档文件还原应用程序。要使用“剥离和压缩”Oracle JET 应用程序,必须在提取的应用程序中恢复项目依赖关系,包括 Oracle JET 工具以及所需的库和模块。

  1. 下载 jet_web_application_masterdetail_final.zip 文件并将已完成应用程序的内容提取到 jet_web_application_masterdetail_final 文件夹。

  2. 在终端窗口中,导航到 jet_web_application_masterdetail_final 文件夹并恢复 Oracle JET Web 应用程序。

    $ ojet restore
    
  3. 等待确认。

    . . .
    Success: Restore complete
    

    应用程序已准备好运行。

  4. 运行 Web 应用程序并在浏览器中对其进行测试。

    $ ojet serve
    
  5. 关闭显示正在运行的 Web 应用程序的浏览器窗口或选项卡。

  6. 在终端窗口中,按 Ctrl+C,如果出现提示,输入 y 以退出 Oracle JET 工具批处理作业。

更多学习资源

docs.oracle.com/learn 上浏览其他实验室,或者在 Oracle Learning YouTube 渠道上访问更多免费学习内容。此外,访问 education.oracle.com/learning-explorer 以成为 Oracle Learning Explorer。

有关产品文档,请访问 Oracle 帮助中心