问题
Problem
I am trying to write a Single Page Application (SPA) where initially the app shows module "A". When the user clicks an element in "A", module "B" is displayed and is passed an ID from A. (For example A displays a list of Employee IDs, clicking on one employee means B will display details of that employee)
Initially my URL is :
http://localhost:8000/
Clicking on an item in A with an id of 123, the URL changes to following which is correct:
http://localhost:8000/A/123
However, I get the following error
GET http://localhost:8000/b/js/viewModels/B.js net::ERR_ABORTED 404 (Not Found)
ojModule failed to load viewModels/B
ojlogger.js:257 Error: Script error for "viewModels/B"
I do not know why it has changed the path and added an extra "/b/" to get the B.js/B.html file. Of course it can not find this file as there is no such folder "b" in my project structure.
Oracle Jet Cookbook Sample
https://www.oracle.com/webfolder/technetwork/jet/jetCookbook.html?component=router&demo=stateParams
I am using the sample in the OracleJet Cookbook for a Router with State Parameters. If you open this example in full screen you see that the URL for the first screen (A) is
https://www.oracle.com/webfolder/technetwork/jet/content/router-stateParams/demo.html
Clicking on a person in the list changes the URL to the following, which is the same as mine.
https://www.oracle.com/webfolder/technetwork/jet/content/router-stateParams/demo.html/detail/7566
This cookbook sample does not error like mine.
My Code
project structure
src
|- index.html
|- js
|- main.js
|- viewModels
|- A.js
|- B.js
|- views
|- A.html
|- B.html
index.html
....
<body>
<div id="routing-container">
<div data-bind="ojModule:router.moduleConfig"></div>
</div>
</body>
....
main.js
requirejs.config(
{
baseUrl: 'js',
....
}
require(['ojs/ojbootstrap', 'ojs/ojrouter', 'knockout', 'ojs/ojmodule-element-utils', 'ojs/ojknockout', 'ojs/ojmodule'],
function (Bootstrap, Router, ko) {
// Retrieve the router static instance and configure the states
var router = Router.rootInstance;
router.configure({
'a': {label: 'a', value: 'A', isDefault: true},
'b/{id}': {label: 'b', value: 'B' }
});
var viewModel = {
router: router
};
Bootstrap.whenDocumentReady().then(
function(){
ko.applyBindings(viewModel, document.getElementById('routing-container'));
Router.sync();
}
);
});
A.html
....
<div on-click="[[onClicked]]" >
....
</div>
...
A.js
define(['ojs/ojcore', 'ojs/ojrouter', 'knockout', '],
function (oj, Router, ko) {
function AViewModel(params) {
....
router = Router.rootInstance;
....
this.onClicked= function(event) {
router.go('b/'+ 123);
}
....
};
}
return AViewModel;
}
Attempts
I have tried adding one of the following in "main.js" and it doesn't make a difference.
Router.defaults['baseUrl'] = '';
Router.defaults['baseUrl'] = 'js';
Router.defaults['baseUrl'] = '/js';
Router.defaults['baseUrl'] = '/js/';
回答1:
Updated answer after gleeming more information
I have finally resolved this with some advice from a colleague.
Make sure the "baseUrl" specified in your requireJS is absolute when you are using the urlPathAdapter router.
main.js
requirejs.config(
{
baseUrl: '/js',
RequireJS's baseUrl is used as the starting location for RequireJS to download its relative content. Most of the time its set to "js" but that will not work nicely with the UrlPathAdapter router. This is because the router will change the URL which RequireJS tries to add its path to when its not absolute. The result is that the path requireJS is trying to use to get its content is invalid.
For example:
- you accessed your app with the URL "protocol://server:port/my/app"
- RequireJS will try and access content by appending "js", for example "protocol://server:port/my/app/js/viewModel/..." which works when you are at the root of your application
- you use the router to navigate to a different url, the url is now "protocol://server:port/my/app/newPath"
- now RequireJS will try and use the URL "protocol://server:port/my/app/newPath/js/viewModel" which is wrong
- When the RequireJS baseURL is absolute, it will always be added to the apps URL, for example "protocol://server:port/my/app/js/viewModel" where the content will be found
NOTE: I also ensured the baseUrl in "path-mapping" was absolute as well path_mapping.json
{
"baseUrl": "/js",
Another solution was to change my router adapter from the default urlPathAdapter to urlParamAdapter.
Router.defaults.urlAdapter = new Router.urlParamAdapter();
var router = Router.rootInstance;
来源:https://stackoverflow.com/questions/58490944/oracle-jet-routing-is-adding-extra-folder-in-path-when-trying-to-get-child-modul