Oracle Jet 如何创建主要细节 SPA?
Oracle Jet how do i create a master detail SPA?
背景
我正在尝试编写一个单页应用程序 (SPA),该应用程序具有 Master -> Detail 结构,因此单击屏幕中的项目会过滤到其他 listings/details。
例如我有以下
- 类别列表:列出食物类别(即奶制品、肉类等)。当您单击这些类别之一时,类别列表将替换为食谱列表
- 食谱列表:显示所选类别中食物的食谱列表。单击食谱后,食谱列表将替换为食谱详细信息
- 配方详细信息:显示所选配方的详细信息
我正在尝试使用 Oracle Jet 编写此代码。我创建了 3 个模块
- CategoryListModule 和 CategoryListItemModule(采用 categoryId)
- RecipeListModule(采用 categoryId)和 RecipeListItemModule(采用 recipeId)
- RecipeDetailsModule(采用 recipeId)
在每个模块中,它使用第 3 方库从服务器获取数据。对于前 2 个模块,主模块获取要显示的基本项目列表(即 CategoryList 获取类别 IDS 列表),其子模块获取该特定项目的完整信息(例如 CategoryListItemModule 调用服务器以获取该类别的所有显示信息)
CategoryListModule.html
<oj-bind-for-each data="[[categoryIds]]" as="categoryId">
<template>
<div data-bind="ojModule:
{name: 'CategoryListItemModule',
params:{categoryId: categoryId} }">
</div>
</template>
</oj-bind-for-each>
CategoryListItemModule.html
<div >
<div data-bind="text:categoryTitle"></div>
<div data-bind="text:text:categoryDescription"></div>
</div>
路由器在main.js
我在 main.js 中创建了一个路由器,如下所示
self.router = oj.Router.rootInstance;
self.router.configure({
'categoryList':
{label: 'CategoryListModule',
value: 'CategoryListModule',
isDefault: true},
'recipeList':
{label: 'RecipeListModule',
value: 'RecipeListModule'},
'recipeDetails':
{label: 'RecipeDetailsModule',
value: 'RecipeDetailsModule'}
});
var viewModel = {
router: router
}
Bootstrap.whenDocumentReady().then(
function() {
ko.applyBindings(viewModel);
}
);
问题
我不知道如何编写用户点击特定类别并将用户带到食谱列表的代码。
在 Vue/Angular/React 中,我在 html 周围用 link 编码,用于告诉路由器去哪里的类别列表项,例如在 Vue 中,它类似于正在关注
<router-link :to="{ name: 'recipesList', params: { categoryId: categoryId}}">
<div>{{categoryTitle}}</div>
<div>{{categoryDescription}}</div>
</router-link>
我看到了路由器的示例,但它似乎与我未使用的 Jet 组件有关。例如,在 Cookbook 中有简单路由器示例
HTML
<oj-bind-for-each data="[[router.states]]">
<template>
<oj-option value="[[$current.data.id]]">
<span><oj-bind-text value="[[$current.data.label]]"></oj-bind-text></span>
</oj-option>
</template>
</oj-bind-for-each>
JAVA SCRIPT
var router = Router.rootInstance;
router.configure(
{
'pref': { label: 'Preface', value: 'This is the Preface.',
isDefault: true },
'chap1': { label: 'Chapter 1', value: 'This is Chapter 1.' },
'chap2': { label: 'Chapter 2', value: 'This is Chapter 2.' },
'chap3': { label: 'Chapter 3', value: 'This is Chapter 3.' }
});
var viewModel =
{
router: router
};
我假设在此示例中,Oracle Jet 框架正在处理 "oj-option" 组件对列表中项目的单击,因为我在任何地方都看不到 "onClick" 代码。
我看到你可以在 Jet 中进行事件绑定,并在代码中促使路由器进行路由,但我确信这不是正确的解决方案(例如,我可以用 or 和在 JavaScript 中有一个 onClick 侦听器来告诉路由器转到下一个屏幕。
如有任何关于如何实现此类导航的建议,我们将不胜感激。
更新
我对此有了更多了解。我发现了如何使用代码告诉路由器进行路由。所以在我的 "CategoryListItemModule.html" 中我添加了一个 "onClick" 到 div
<div on-click="[[onClicked]]>
<div data-bind="text:categoryTitle"></div>
<div data-bind="text:text:categoryDescription"></div>
</div>
我已将 "main.js" 中的路由器配置更改为
self.router = oj.Router.rootInstance;
self.router.configure({
'categoryList':
{label: 'CategoryListModule',
value: 'CategoryListModule',
isDefault: true},
'recipeList/{id}':
{label: 'RecipeListModule',
value: 'RecipeListModule'},
'recipeDetails':
{label: 'RecipeDetailsModule',
value: 'RecipeDetailsModule'}
});
在"CategoryListItemModule.js"中获取路由器并实现"onClicked"方法
define(['ojs/ojcore', 'ojs/ojrouter', 'knockout', '],
function (oj, Router, ko) {
function AViewModel(params) {
....
router = Router.rootInstance;
....
this.onClicked= function(event) {
router.go('recipes/'+ categoryId);
}
....
};
....
现在,当用户单击类别列表中的特定类别(例如 id 123)时,将调用 "onClicked" 函数,它告诉路由器路由到“/recipeList/123 应该加载可从该模块内部访问 ID 为 123 的 RecipeListModule。
然而,这仍然无法正常工作,因为 Jet 无法找到 RecipeListModule 。js/RecipeListModule.html 因为它用于尝试在我的项目中查找这些文件的路径有一个额外的 "recipes" 在路径中。我已将此问题的以下内容单独记录到最后一篇。
我原来的更新post展示了创建master -> detail SPA的解决方案。
剩下的问题我放在一个单独的 post 中也有解决方案。
背景
我正在尝试编写一个单页应用程序 (SPA),该应用程序具有 Master -> Detail 结构,因此单击屏幕中的项目会过滤到其他 listings/details。 例如我有以下
- 类别列表:列出食物类别(即奶制品、肉类等)。当您单击这些类别之一时,类别列表将替换为食谱列表
- 食谱列表:显示所选类别中食物的食谱列表。单击食谱后,食谱列表将替换为食谱详细信息
- 配方详细信息:显示所选配方的详细信息
我正在尝试使用 Oracle Jet 编写此代码。我创建了 3 个模块
- CategoryListModule 和 CategoryListItemModule(采用 categoryId)
- RecipeListModule(采用 categoryId)和 RecipeListItemModule(采用 recipeId)
- RecipeDetailsModule(采用 recipeId)
在每个模块中,它使用第 3 方库从服务器获取数据。对于前 2 个模块,主模块获取要显示的基本项目列表(即 CategoryList 获取类别 IDS 列表),其子模块获取该特定项目的完整信息(例如 CategoryListItemModule 调用服务器以获取该类别的所有显示信息)
CategoryListModule.html
<oj-bind-for-each data="[[categoryIds]]" as="categoryId">
<template>
<div data-bind="ojModule:
{name: 'CategoryListItemModule',
params:{categoryId: categoryId} }">
</div>
</template>
</oj-bind-for-each>
CategoryListItemModule.html
<div >
<div data-bind="text:categoryTitle"></div>
<div data-bind="text:text:categoryDescription"></div>
</div>
路由器在main.js
我在 main.js 中创建了一个路由器,如下所示
self.router = oj.Router.rootInstance;
self.router.configure({
'categoryList':
{label: 'CategoryListModule',
value: 'CategoryListModule',
isDefault: true},
'recipeList':
{label: 'RecipeListModule',
value: 'RecipeListModule'},
'recipeDetails':
{label: 'RecipeDetailsModule',
value: 'RecipeDetailsModule'}
});
var viewModel = {
router: router
}
Bootstrap.whenDocumentReady().then(
function() {
ko.applyBindings(viewModel);
}
);
问题
我不知道如何编写用户点击特定类别并将用户带到食谱列表的代码。
在 Vue/Angular/React 中,我在 html 周围用 link 编码,用于告诉路由器去哪里的类别列表项,例如在 Vue 中,它类似于正在关注
<router-link :to="{ name: 'recipesList', params: { categoryId: categoryId}}">
<div>{{categoryTitle}}</div>
<div>{{categoryDescription}}</div>
</router-link>
我看到了路由器的示例,但它似乎与我未使用的 Jet 组件有关。例如,在 Cookbook 中有简单路由器示例
HTML
<oj-bind-for-each data="[[router.states]]">
<template>
<oj-option value="[[$current.data.id]]">
<span><oj-bind-text value="[[$current.data.label]]"></oj-bind-text></span>
</oj-option>
</template>
</oj-bind-for-each>
JAVA SCRIPT
var router = Router.rootInstance;
router.configure(
{
'pref': { label: 'Preface', value: 'This is the Preface.',
isDefault: true },
'chap1': { label: 'Chapter 1', value: 'This is Chapter 1.' },
'chap2': { label: 'Chapter 2', value: 'This is Chapter 2.' },
'chap3': { label: 'Chapter 3', value: 'This is Chapter 3.' }
});
var viewModel =
{
router: router
};
我假设在此示例中,Oracle Jet 框架正在处理 "oj-option" 组件对列表中项目的单击,因为我在任何地方都看不到 "onClick" 代码。
我看到你可以在 Jet 中进行事件绑定,并在代码中促使路由器进行路由,但我确信这不是正确的解决方案(例如,我可以用 or 和在 JavaScript 中有一个 onClick 侦听器来告诉路由器转到下一个屏幕。
如有任何关于如何实现此类导航的建议,我们将不胜感激。
更新
我对此有了更多了解。我发现了如何使用代码告诉路由器进行路由。所以在我的 "CategoryListItemModule.html" 中我添加了一个 "onClick" 到 div
<div on-click="[[onClicked]]>
<div data-bind="text:categoryTitle"></div>
<div data-bind="text:text:categoryDescription"></div>
</div>
我已将 "main.js" 中的路由器配置更改为
self.router = oj.Router.rootInstance;
self.router.configure({
'categoryList':
{label: 'CategoryListModule',
value: 'CategoryListModule',
isDefault: true},
'recipeList/{id}':
{label: 'RecipeListModule',
value: 'RecipeListModule'},
'recipeDetails':
{label: 'RecipeDetailsModule',
value: 'RecipeDetailsModule'}
});
在"CategoryListItemModule.js"中获取路由器并实现"onClicked"方法
define(['ojs/ojcore', 'ojs/ojrouter', 'knockout', '],
function (oj, Router, ko) {
function AViewModel(params) {
....
router = Router.rootInstance;
....
this.onClicked= function(event) {
router.go('recipes/'+ categoryId);
}
....
};
....
现在,当用户单击类别列表中的特定类别(例如 id 123)时,将调用 "onClicked" 函数,它告诉路由器路由到“/recipeList/123 应该加载可从该模块内部访问 ID 为 123 的 RecipeListModule。
然而,这仍然无法正常工作,因为 Jet 无法找到 RecipeListModule 。js/RecipeListModule.html 因为它用于尝试在我的项目中查找这些文件的路径有一个额外的 "recipes" 在路径中。我已将此问题的以下内容单独记录到最后一篇。
我原来的更新post展示了创建master -> detail SPA的解决方案。
剩下的问题我放在一个单独的 post 中也有解决方案。