我用Knockout和jQuery制作了SPA。 该页面由通过Require注册的剔除组件组成。我有不同种类的组件(如页面视图)和更具体的组件(如搜索栏)。
我不使用链接来更改视图,但在index.html中具有此逻辑以加载到不同的视图/ HTML中:
<ul class="navbar-nav mr-auto" data-bind="foreach: menuItems">
<!-- <li class="nav-item" data-bind="css: $parent.isActive($data)">-->
<a href="#" class="nav-link" data-bind="click: $parent.changeMenu">
<span class="myMenuItem" data-bind="text: name, page-href: name"></span>
</a>
<!--</li>-->
</ul>
<div data-bind="component: { name: selectedComponent, params: selectedParams}"></div>
因此,我可以单击navLink来更改菜单。因为changeMenu更改了所选组件。这在我的主应用程序中运行:
var menuItems = [
{ name: 'Home ', component: 'home-view' },
{ name: 'MyPage ', component: 'my-page-view' },
{ name: 'Post ', component: 'single-post' },
{ name: 'Log In ', component: 'login-view' }
];
var selectedMenu = ko.observable(menuItems[0]);
var selectedComponent = ko.observable('home-view');
var selectedParams = ko.observable({});
var changeMenu = function (menu) {
selectedMenu(menu);
selectedComponent(menu.component);
};
我希望pager.js成为该结构的一部分,但是经过大约8个小时的浏览和测试pager.js API示例后,我仍然没有找到实现此目的的方法。
<a data-bind="page-href: name"></a>
menuItems foreach循环中的此链接在组件名称后进行链接,但内容未更改。这是有道理的,因为它没有运行changeMenu方法。因此,我最好的“逻辑”告诉我,我可以将此行与以下内容结合起来:
<a href="#" class="nav-link" data-bind="click: $parent.changeMenu">
如果这不可能,则可以将链接绑定到不同的组件视图。因此,当成功加载我的主页视图时,哈希页面绑定就会更改。
当前的一个示例是myPage组件:
视图:
<h3>MyPage</h3>
<h4>Favorites:</h4>
<favorites-list></favorites-list>
<h4>History:</h4>
<history-list-view></history-list-view>
该视图包含一个带有历史列表视图的组件。而且这个有一个带有逻辑来检索数据的视图模型。
viewModel:
define(['knockout', 'dataService', 'postman'], function (ko, ds, postman) {
return function (params) {
var histories = ko.observableArray([]);
var favorites = ko.observableArray([]);
var favoriteNext = ko.observable();
var favoritePrev = ko.observable();
var currentUser = ko.observable();
var currentComponent = ko.observable("history");
var favoritesComponent = ko.observable("favorite");
postman.subscribe("user", function (user) {
currentUser(user.Username);
});
var getUserInformation = function () {
ds.getUser(function (data) {
histories(data[1]);
}, currentUser());
};
var getUserFavorites = function () {
ds.getFavorites(function (data) {
favorites(data.items);
favoriteNext(data.next);
favoritePrev(data.Prev);
}, currentUser());
}
postman.publish("needUserData");
getUserInformation();
getUserFavorites();
return {
histories,
currentComponent,
favoritesComponent,
favorites
};
};
});
要检索数据,请使用我的数据服务:
var getUser = function (callback, user) {
$.getJSON('api/user/myPage/' + user, function (data) {
callback(data);
});
};
这是我第一次尝试向您询问答案,我希望有什么道理。我只是无法理解与构造淘汰SPA的组件方式有关的关于异步部分的API。那是我需要的还是应该朝一个全新的方向走?
https://pagerjs.com/demo/#!/navigation/async/ok
顺便说一句,我以这种方式启动了寻呼机:
require(['knockout', 'app', 'pager'], function (ko, app, pager) {
pager.extendWithPage(app);
ko.applyBindings(app);
pager.start();
});
一切都正确安装,因为我可以使用简单的代码示例,但是主要问题是是否可以通过此基于组件的菜单实现Pager.js?
更新16/01/2019
我仍然有麻烦,但是我认为我发现在每个页面组件的index.html中都需要有这样的页面:
<div data-bind="page: {
id: 'homePage',
title: 'HomePage',
withOnShow: requireVM('vm/navigation/async'),
desc: 'page with searchbar',
scrollToTop: true,
sourceCache: true,
sourceOnShow: 'page/homePage'}"
我不明白如何使用withOnShow参数,但是可以看到它是一种显示我将使用哪种viewmodel的方式?
我试图通过API https://pagerjs.com/demo/
使demo.js启发了viewModel。 define(['jquery', 'knockout', 'dataService', 'postman', 'jqcloud'], function ($, ko, ds, postman) {
var searchString = ko.observable();
var vm = {
test: "Pelle",
// wait 2 secs before returning ok
wait2: function () {
var d = $.Deferred();
setTimeout(function () {
d.resolve();
}, 2000);
return d;
},
wait2Fail: function () {
var d = $.Deferred();
setTimeout(function () {
d.reject();
}, 2000);
return d;
},
okIsLoading: ko.observable(),
notOkIsLoading: ko.observable()
};
return {
getVM: function() {
return vm;
}, searchString
};
});
但是以这种方式调用页面时:
<a class="btn" data-bind="click: $page.homePage(wait2,'ok','notok',okIsLoading)">
Show OK page after 2 secs
<!-- ko if: (okIsLoading() == 'pending') -->
<img src="small-ajax-loader.gif"/>
<!-- /ko -->
</a>
我收到一个“ knockout.debug.js:3391未捕获的ReferenceError:无法处理绑定”单击:function(){return $ page.homePage(wait2,'ok','notok',okIsLoading)}“ 消息:未定义$ page”
如果不给$ page一个ID,API不会告诉我如何定义$ page的任何信息?