使用Knockout组件的一些问题(使用RequireJS加载)
Some questions working with Knockout components (using RequireJS for loading)
我目前正在开发一个测试网络应用程序来测试 Knockout 的组件功能。我使用 RequireJS 来加载组件。虽然我能够这样做,但我在某些地方卡住了,而在某些地方,我不确定我是否做对了。
该应用程序包含一个带有 header 的页面、一个左侧边栏,以及 space 上的内容区域保留在右侧。这3个都注册为组件。左侧栏用作导航并有一个无序列表,其中列表项通过执行 AJAX 调用来填充。单击列表项时,右侧的内容应显示与单击的列表项对应的component/view。
有了这些,我的问题是:
我只能加载实际组件中左侧栏的项目。这个可以吗?我的意思是,当加载左侧栏组件时,它会执行 AJAX 调用,然后在其视图模型上加载数据。我这样做是因为这是我唯一能想到的将数据加载到视图模型的方法。实际上,我更喜欢在应用程序启动时加载数据,然后在侧边栏加载时将数据放入其中。所以我的问题是:我采用的方法是否可行,是否可以采用我喜欢的方法?如果是,怎么办?
我不知道如何正确传达侧边栏中的点击以显示右侧的内容。我怎样才能做到这一点相互依赖最少,或者我怎样才能做到这一点?
带有视图模型的 parent 组件是否可以在其模板中包含 child 组件,但 child 组件从 parent 查看模型?如果可以,怎么做?
这些问题让我阅读了好几天,但仍然无法正常工作或仍然感到困惑。如果您只有一个项目的答案,请不要犹豫post。希望所有问题都能得到答复。
编辑(源代码)
为header:
模板
<div>
</div>
虚拟机
define(["text!./admin-main-header.html"], function(template) {
function AdminMainHeaderViewModel() {
}
return { viewModel: AdminMainHeaderViewModel, template: template };
});
对于边栏:
模板
<div class="vmsc" data-bind="with: adminModules, vertMenu: adminModules">
<ul data-bind="foreach: modules">
<li class="has-sub"><a href="javascript:void(0);"><span data-bind="text: name"></span></a>
<ul data-bind="foreach: $data.submodules">
<li><a href="javascript:void(0);"><span data-bind="text: name"></span></a></li>
</ul>
</li>
</ul>
</div>
虚拟机
define(["jquery", "knockout", "ko-mapping",
"jquery-vertmenusc", "text!./vert-menu.html"], function($, ko, komap, vmsc, template) {
ko.mapping = komap;
function VertMenuScViewModel() {
var self = this;
self.adminModules = ko.observable();
$.get("http://localhost:8080/_mock_data/admin-modules.txt", function(data) {
self.adminModules(ko.mapping.fromJSON(data));
});
}
return { viewModel: VertMenuScViewModel, template: template };
});
对应内容:
模板
<div>
</div>
虚拟机
define(["text!./admin-main-content.html"], function(template) {
function AdminMainContentViewModel() {
}
return { viewModel: AdminMainContentViewModel, template: template };
});
主要HTML:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Sample</title>
<!-- Scripts -->
<script src="js/require.min.2.1.20.js" data-main="js/app/require.config.js"></script>
</head>
<body>
<div>
<admin-main-header></admin-main-header>
<div>
<admin-main-nav></admin-main-nav>
<admin-main-content></admin-main-content>
</div>
</div>
</body>
</html>
内容中还没有代码,因为我不知道应该如何传递数据。我希望这些附加信息能有所帮助。谢谢。
我认为对您帮助最大的功能是 using params in the components。我开始使用您的示例代码,但它太复杂了,无法制作一个简单的工作示例。但是你的 parent HTML 可能看起来像这样:
<div>
<admin-main-nav params='lastClicked:chosen'></admin-main-nav>
<admin-main-content params='toDisplay:chosen'></admin-main-content>
</div>
其中 chosen
是您主视图模型中的可观察对象。您的导航视图模型构造函数可能以类似
的内容开始
function VertMenuScViewModel(params) {
var self = this;
self.adminModules = ko.observable();
self.lastClicked = params.lastClicked;
所以现在导航视图模型的 lastClicked
成员与 parent 中的 chosen
是相同的可观察对象。这就是您可以将可观察对象共享到组件的方式。例如,您可以让 nav 组件写入它,而 content 组件从中读取(以设置其内容)。他们都不了解对方,他们只知道他们被赋予了一个可观察的对象以用于某个目的。
这也是您在主视图模型中加载数据并将其传递给导航组件的方法。
我目前正在开发一个测试网络应用程序来测试 Knockout 的组件功能。我使用 RequireJS 来加载组件。虽然我能够这样做,但我在某些地方卡住了,而在某些地方,我不确定我是否做对了。
该应用程序包含一个带有 header 的页面、一个左侧边栏,以及 space 上的内容区域保留在右侧。这3个都注册为组件。左侧栏用作导航并有一个无序列表,其中列表项通过执行 AJAX 调用来填充。单击列表项时,右侧的内容应显示与单击的列表项对应的component/view。
有了这些,我的问题是:
我只能加载实际组件中左侧栏的项目。这个可以吗?我的意思是,当加载左侧栏组件时,它会执行 AJAX 调用,然后在其视图模型上加载数据。我这样做是因为这是我唯一能想到的将数据加载到视图模型的方法。实际上,我更喜欢在应用程序启动时加载数据,然后在侧边栏加载时将数据放入其中。所以我的问题是:我采用的方法是否可行,是否可以采用我喜欢的方法?如果是,怎么办?
我不知道如何正确传达侧边栏中的点击以显示右侧的内容。我怎样才能做到这一点相互依赖最少,或者我怎样才能做到这一点?
带有视图模型的 parent 组件是否可以在其模板中包含 child 组件,但 child 组件从 parent 查看模型?如果可以,怎么做?
这些问题让我阅读了好几天,但仍然无法正常工作或仍然感到困惑。如果您只有一个项目的答案,请不要犹豫post。希望所有问题都能得到答复。
编辑(源代码)
为header:
模板
<div>
</div>
虚拟机
define(["text!./admin-main-header.html"], function(template) {
function AdminMainHeaderViewModel() {
}
return { viewModel: AdminMainHeaderViewModel, template: template };
});
对于边栏:
模板
<div class="vmsc" data-bind="with: adminModules, vertMenu: adminModules">
<ul data-bind="foreach: modules">
<li class="has-sub"><a href="javascript:void(0);"><span data-bind="text: name"></span></a>
<ul data-bind="foreach: $data.submodules">
<li><a href="javascript:void(0);"><span data-bind="text: name"></span></a></li>
</ul>
</li>
</ul>
</div>
虚拟机
define(["jquery", "knockout", "ko-mapping",
"jquery-vertmenusc", "text!./vert-menu.html"], function($, ko, komap, vmsc, template) {
ko.mapping = komap;
function VertMenuScViewModel() {
var self = this;
self.adminModules = ko.observable();
$.get("http://localhost:8080/_mock_data/admin-modules.txt", function(data) {
self.adminModules(ko.mapping.fromJSON(data));
});
}
return { viewModel: VertMenuScViewModel, template: template };
});
对应内容:
模板
<div>
</div>
虚拟机
define(["text!./admin-main-content.html"], function(template) {
function AdminMainContentViewModel() {
}
return { viewModel: AdminMainContentViewModel, template: template };
});
主要HTML:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Sample</title>
<!-- Scripts -->
<script src="js/require.min.2.1.20.js" data-main="js/app/require.config.js"></script>
</head>
<body>
<div>
<admin-main-header></admin-main-header>
<div>
<admin-main-nav></admin-main-nav>
<admin-main-content></admin-main-content>
</div>
</div>
</body>
</html>
内容中还没有代码,因为我不知道应该如何传递数据。我希望这些附加信息能有所帮助。谢谢。
我认为对您帮助最大的功能是 using params in the components。我开始使用您的示例代码,但它太复杂了,无法制作一个简单的工作示例。但是你的 parent HTML 可能看起来像这样:
<div>
<admin-main-nav params='lastClicked:chosen'></admin-main-nav>
<admin-main-content params='toDisplay:chosen'></admin-main-content>
</div>
其中 chosen
是您主视图模型中的可观察对象。您的导航视图模型构造函数可能以类似
function VertMenuScViewModel(params) {
var self = this;
self.adminModules = ko.observable();
self.lastClicked = params.lastClicked;
所以现在导航视图模型的 lastClicked
成员与 parent 中的 chosen
是相同的可观察对象。这就是您可以将可观察对象共享到组件的方式。例如,您可以让 nav 组件写入它,而 content 组件从中读取(以设置其内容)。他们都不了解对方,他们只知道他们被赋予了一个可观察的对象以用于某个目的。
这也是您在主视图模型中加载数据并将其传递给导航组件的方法。