Knockout.js 可组合组件?
Knockout.js composable components?
我正在考虑使用 Knockout.js 创建可重用的组件。但是,通过阅读文档,我不知道如何实现一个可以在其中容纳其他(每次使用可能不同)组件的组件。
例如,我想实现一个 side-menu-view 组件,它包含一个带有菜单按钮的标题栏、一个菜单面板和一个内容面板。不应预先定义菜单和内容面板的内容。例如,在一个用例中,我会将 list-view 组件放入菜单面板中,在另一个用例中,我可以将复选框列表放入菜单面板中。
据我从文档中了解到,在 Knockout.js 中,组件的模板必须完全定义,并且不提供以后可以插入其他组件的位置。还是我错了?可以吗?谢谢!
更新:
我想创建一个组件,它可以用作:
<side-menu-view>
<menu>
<!-- I can put anything here -->
</menu>
<content>
<!-- I can put anything here -->
</content>
</side-menu-view>
我知道组件的 child 节点可以通过 $componentTemplateNodes 访问,但是我希望能够分别获取 <menu>
和 <content>
的内容,并且把它放在我的组件布局的适当位置。
更新 2:
使用示例:
<side-menu-view>
<menu>
This is a menu!
</menu>
<content>
This is content!
</content>
</side-menu-view>
或者像这样:
<side-menu-view>
<menu>
<ul>
<li><a href="#">1</a></li>
<li><a href="#">2</a></li>
<li><a href="#">3</a></li>
</ul>
</menu>
<content>
<h1>Title</h1>
<p>Some text</p>
</content>
</side-menu-view>
Knockout 的模型可以 "pre-defined" 用于一般用途,然后针对特定用途进行扩展。这意味着:
- 像往常一样创建一个 object/model
- 创建具有扩展属性的 object/model
- 混合两个模型,即 jQuery 的 $.extend
示例:
var mainModel = function () {
this.blablabla = ko.observable('blablabla');
}
var extendedModel = function () {
this.sup = ko.observable('sup');
}
var myModelInstance = $.extend({}, new mainModel(), new extendedModel());
console.log(myModelInstance.blablabla(), myModelInstance.sup()); // "blablabla", "sup"
如果您使用的是自定义 html 元素语法,那么您是对的,您在编写 html 时必须知道这些组件,例如:
<menu-panel>
<list params="..."/>
</menu-panel>
但是,您有 component binding 可以让您在 运行 时间选择组件:
<menu-panel>
<div data-bind="component: {
name: yourDynamicComponentName,
params: { ... },
}"/>
</menu-panel>
请注意,当然,yourDynamicComponentName
仍必须注册,以便 knockout 知道在哪里可以找到它。
回复:更新 2(仅关注 menu
控件,因为它显然与 content
控件相似):
所以你只需要定义两个组件,一个叫做menu-list
,一个叫做menu-static
:
// html for a component called "menu-list"
<ul>
<li><a href="#">1</a></li>
<li><a href="#">2</a></li>
<li><a href="#">3</a></li>
</ul>
// html for a component called "menu-static"
This is a menu!
并且在您的 viewModel
for side-menu-view
中,您可以有一个名为 menuType
的 属性,并且您可以在 html for [=] 中使用它20=] 像这样:
// html for "side-menu-view"
<div data-bind="component: { name: menuType }"/>
现在您可以设置 menuType('menu-static')
或 menuType('menu-list')
来切换菜单类型。
我正在考虑使用 Knockout.js 创建可重用的组件。但是,通过阅读文档,我不知道如何实现一个可以在其中容纳其他(每次使用可能不同)组件的组件。
例如,我想实现一个 side-menu-view 组件,它包含一个带有菜单按钮的标题栏、一个菜单面板和一个内容面板。不应预先定义菜单和内容面板的内容。例如,在一个用例中,我会将 list-view 组件放入菜单面板中,在另一个用例中,我可以将复选框列表放入菜单面板中。
据我从文档中了解到,在 Knockout.js 中,组件的模板必须完全定义,并且不提供以后可以插入其他组件的位置。还是我错了?可以吗?谢谢!
更新:
我想创建一个组件,它可以用作:
<side-menu-view>
<menu>
<!-- I can put anything here -->
</menu>
<content>
<!-- I can put anything here -->
</content>
</side-menu-view>
我知道组件的 child 节点可以通过 $componentTemplateNodes 访问,但是我希望能够分别获取 <menu>
和 <content>
的内容,并且把它放在我的组件布局的适当位置。
更新 2:
使用示例:
<side-menu-view>
<menu>
This is a menu!
</menu>
<content>
This is content!
</content>
</side-menu-view>
或者像这样:
<side-menu-view>
<menu>
<ul>
<li><a href="#">1</a></li>
<li><a href="#">2</a></li>
<li><a href="#">3</a></li>
</ul>
</menu>
<content>
<h1>Title</h1>
<p>Some text</p>
</content>
</side-menu-view>
Knockout 的模型可以 "pre-defined" 用于一般用途,然后针对特定用途进行扩展。这意味着:
- 像往常一样创建一个 object/model
- 创建具有扩展属性的 object/model
- 混合两个模型,即 jQuery 的 $.extend
示例:
var mainModel = function () {
this.blablabla = ko.observable('blablabla');
}
var extendedModel = function () {
this.sup = ko.observable('sup');
}
var myModelInstance = $.extend({}, new mainModel(), new extendedModel());
console.log(myModelInstance.blablabla(), myModelInstance.sup()); // "blablabla", "sup"
如果您使用的是自定义 html 元素语法,那么您是对的,您在编写 html 时必须知道这些组件,例如:
<menu-panel>
<list params="..."/>
</menu-panel>
但是,您有 component binding 可以让您在 运行 时间选择组件:
<menu-panel>
<div data-bind="component: {
name: yourDynamicComponentName,
params: { ... },
}"/>
</menu-panel>
请注意,当然,yourDynamicComponentName
仍必须注册,以便 knockout 知道在哪里可以找到它。
回复:更新 2(仅关注 menu
控件,因为它显然与 content
控件相似):
所以你只需要定义两个组件,一个叫做menu-list
,一个叫做menu-static
:
// html for a component called "menu-list"
<ul>
<li><a href="#">1</a></li>
<li><a href="#">2</a></li>
<li><a href="#">3</a></li>
</ul>
// html for a component called "menu-static"
This is a menu!
并且在您的 viewModel
for side-menu-view
中,您可以有一个名为 menuType
的 属性,并且您可以在 html for [=] 中使用它20=] 像这样:
// html for "side-menu-view"
<div data-bind="component: { name: menuType }"/>
现在您可以设置 menuType('menu-static')
或 menuType('menu-list')
来切换菜单类型。