• Oracle JET 单页面应用程序Router 使用(上)


      单页面应用程序:使用一个进加载一次的网页,如果页面由于用户的交互而改变,则仅绘制更改的页面部分。

      要创建单页面应用程序需要使用 oj.Router 的虚拟导航来支持,ojModule 用来响应页面的重新绘制。 ojModule 仅用于分离的 view 和 viewMode ,使之与页面通过 Knockout绑定。另外,ojModule 可选,当不使用分离视图与模型时,可直接在元素上响应变化。

      1.简单模型:

      

      当选择 Chapter1 或其他时,将显示新内容,并且URL更改以反映用户在页面上当前的位置。

      

      2.路由器适配器

      路由器带有两个URL适配器。每个适配器定义如何将URL格式化表示。

        urlPathAdapter:在路径段中格式化 URL 。每个段都是的当前状态 id ,由 ‘ / ’ 分隔,如: localhost:8000/chap1

        urlParamAdapter:使用查询参数格式化 URL 。每个参数都是路由器名称及其当前状态 id ,如:localhost:8000/?root=chap1

      路由器的默认适配器是 urlPathAdapter 。需要更改可以使用 方法:

        oj.Router.defaults['urlAdapter'] = new oj.Router.urlParamAdapter

      当路由单页应用程序时,页面不会从头开始加载,但页面内容会动态更改。为了成为浏览器历史的一部分并提供书签内容,Oracle JET 路由器模拟使用 HTML5 历史记录推送状态功能导航的行为。路由器还控制 URL 看起来像传统页面 URL。 这些 URL 没有资源,必须设置 HTML 服务器。这是通过一个重写引擎的简单规则完成的。

      一般来说,当应用程序中用户需求只包含几个视图并且关联状态不是很复杂,则使用查询参数。而路径段显示 URL 则显得 URL 更简洁,特别是使用嵌套路径(添加子路由)。

      ojModule 与 oj.Router 结合使用,可以配置 ojModule 对象,其中模块名称是路由器的状态。当路由器更改状态时,ojModule 将自动加载并呈现当前 RouterState 对象的值得指定模块内容。

      3.简单使用例子:

      (1)appController.js:

    define(['ojs/ojcore', 'knockout', 'ojs/ojknockout', 'ojs/ojrouter', 'ojs/ojbutton', 'ojs/ojtoolbar'],
      function(oj, ko) {
        function ControllerViewModel() {
          var self = this;
    
          self.router = oj.Router.rootInstance;
          self.router.configure({
            'pref': { label: 'Preface', isDefault: true},
            'chap1': { label: 'Chapter 1'},
            'chap2': { label: 'Chapter 2'},
            'chap3' : {label: 'Chapter 3'}
          });
          oj.Router.defaults['urlAdapter'] = new oj.Router.urlParamAdapter;
        }
    
        return new ControllerViewModel();
      }
    );

      a)添加 ojrouter 模块。

          'ojs/ojrouter'

      b)创建路由实例,oj.Router.rootInstance 表示唯一根路由,该路由的名称是 “root” 。

          self.router = oj.Router.rootInstance;

      c)配置路由器状态,属性: label:链接字符串,没有定义标题属性时,用于页面的标题。

                     value:与该状态相关联的对象。

                     isDefault:设置起始页面 

          self.router.configure({
                'pref': { label: 'Preface', isDefault: true},
                'chap1': { label: 'Chapter 1'},
                'chap2': { label: 'Chapter 2'},
                'chap3' : {label: 'Chapter 3'}
              });

      d)URL适配器,可选。   

          oj.Router.defaults['urlAdapter'] = new oj.Router.urlParamAdapter;

      (2)main.js

    require(['ojs/ojcore', 'knockout', 'appController', 'ojs/ojknockout', 'ojs/ojrouter', 'ojs/ojmodule'],
      function (oj, ko, app) { 
        $(function() {  
            oj.Router.sync().then(
              function() {
                ko.applyBindings(app, document.getElementById('routingContainer'));
              },
              function(error) {
                oj.Logger.error('Error in root start: ' + error.message);
              }
            );
        });
      }
    );

      a)添加 ojrouter 模块和 ojmodule(需要使用 ojmodule 时添加)

          'ojs/ojrouter', 'ojs/ojmodule'

      b)将路由器与当前 URL 同步。必须在路由器配置后才能调用,以将 URL 与路由器状态同步。   

          oj.Router.sync().then()

      c)将 appController 挂载到 HTML 上

          ko.applyBindings(app, document.getElementById('routingContainer'))

      (3)index.html

      <div id="routing-container">
          <div id='buttons-container' data-bind="ojComponent: {component:'ojToolbar'}">
            <div data-bind="ojComponent: { component: 'ojButtonset',
                                            checked: router.stateId,
                                            focusManagement: 'none'}">
              <!-- ko foreach: router.states -->
                <label data-bind="attr: {for : id}"></label>
                <input type="radio" name="chapter" data-bind="value: id,
                                                              attr: { id: id},
                                                              ojComponent: { component: 'ojButton',
                                                                              label: label}"/>
              <!-- /ko -->
            </div>
          </div>
          <div data-bind="ojModule: router.moduleConfig"></div>
        </div>

      a)选择时触发状态转换

        定义 checked 属性给予 router.stateId 观察值。它使用双向绑定。当点击一个按钮时,id 被写入到 stateId 中,使路由器状态转换。

      b)观察状态并更新相关部分

          data-bind="ojModule: router.moduleConfig"

        使用需要创建相应的 views 和 viewModels

        

      c) router.states 可以获取到路由配置转化的数组以供遍历展示内容

      

      (4)实际效果如前简单模型相同。

      4.使用子路由

      (1)appController.js

    define(['ojs/ojcore', 'knockout', 'ojs/ojknockout', 'ojs/ojrouter', 'ojs/ojbutton', 'ojs/ojtoolbar', 'ojs/ojnavigationlist'],
      function(oj, ko) {
        function ControllerViewModel() {
          var self = this;
          // 创建根路由
          self.shapeRouter = oj.Router.rootInstance;
          self.shapeRouter.configure({
            'square': { label: 'Square', isDefault: true },
            'circle': { label: 'Circle' },
            'oval': { label: 'Oval'}
          });
          // 创建子路由配置
          self.colorRouter = self.shapeRouter.createChildRouter('color').configure({
            'red': { label: 'Red', isDefault: true },
            'blue': { label: 'Blue' },
            'green': {label: 'Green'}
          });
          self.menuItemSelect = function(event, ui) {
            self.shapeRouter.go(ui.item.children('a').text());
          }
        }
    
        return new ControllerViewModel();
      }
    );

      a)创建根路由

      b)创建子路由并配置

        使用 createChildRouter('name') 创建子路由并添加 configure 配置。

      (function(event, ui) 这里的 event, ui 是 select 带有的属性。另外 optionhange 等也有这两属性)

      (2)main.js 与上例相同

      (3)index.html

    <div id="routing-container"> 
        <!-- 导航栏部分 -->
          <div id="toolbar" data-bind="ojComponent: { component: 'ojToolbar'}">
         <!-- 父路由导航栏部分 --> 
            <div data-bind="ojComponent: { component: 'ojButtonset',
                                           checked: shapeRouter.stateId,
                                           focusManagement: 'none' }">
              <!-- ko foreach: shapeRouter.states -->
                <label data-bind="attr: {for: id}"></label>
                <input type="radio" name="shape" data-bind="value: id, attr: { id: id},
                                                            ojComponent: {component: 'ojButton',
                                                                          label: label}"></input>
              <!-- /ko -->
            </div>
         <!-- 直接跳转指定位置 -->
            <button id="menuButton" data-bind="ojComponent: { component: 'ojButton', label: 'Go to',
                                                              menu: '#gotoMenu'}">
    
            </button>
         <!-- 列表显示跳转位置 --> 
            <ul id="gotoMenu" style="display: none" data-bind="ojComponent: { component: 'ojMenu',
                                                                               select: menuItemSelect }">
              <!-- ko foreach: shapeRouter.states -->
                <li>
                  <a data-bind="text: label"></a>
                  <ul data-bind="foreach: $root.colorRouter.states">
                    <li>
                      <a data-bind="text: '/' + $parent.id + '/' + id"></a>
                    </li>
                  </ul>
                </li>
              <!-- /ko -->
            </ul>        
          </div>
          <hr/>
        <!-- 展示部分 -->
          <div id="pageContent" class="oj-flex oj-flex-items-pad">
         <!-- 子路由导航栏 -->
            <div class="oj-xl-2 oj-lg-2 oj-md-2 oj-sm-12 oj-flex-item">
              <div id="colors" data-bind="ojComponent: { component: 'ojNavigationList',
                                                         selection: colorRouter.stateId,
                                                         drillMode: 'none'}">
                <ul data-bind="foreach: colorRouter.states">
                  <li data-bind="attr: {id: id}">
                    <a data-bind="text: label"></a>
                  </li>
                </ul>
              </div>
            </div>
         <!-- 图形显示 -->
            <div class="oj-xl-10 oj-md-10 oj-sm-12 oj-flex-item">
              <div data-bind="css: shapeRouter.stateId(), style: { background: colorRouter.stateId() }"></div>
            </div>
          </div>
        </div>

      a)stateId 可以让 knockout 观察,而 steteId() 则可以读取当前的 Id 的值。

      (4)CSS

    .square { width: 100px; height: 100px; }
    .circle { width: 100px; height: 100px;
              -moz-border-radius: 50px;
              -webkit-border-radius: 50px;
              border-radius: 50px; }
    .oval   { width: 200px; height: 100px;
              -moz-border-radius: 100px / 50px;
              -webkit-border-radius: 100px / 50px;
              border-radius: 100px / 50px; }

       (5)效果显示:

          

  • 相关阅读:
    CSS文本超出指定行数省略显示
    Vue框架H5商城类项目商品详情点击返回弹出推荐商品弹窗的实现方案
    vue项目强制清除页面缓存
    使用es6的then()方法封装jquery的ajax请求
    微信小程序——微信卡券的领取和查看
    vue项目如何通过前端实现自动识别并配置服务器环境地址
    HTML中的Meta标签详解
    复用微信小程序源码包后仍然有原小程序的版本管理怎么处理
    译: 3. Axis2快速入门指南
    译: 2. Apache Axis2安装指南
  • 原文地址:https://www.cnblogs.com/Easty/p/7225822.html
Copyright © 2020-2023  润新知