使用Knockout组件时替换容器元素 [英] Replace container element when using Knockout component

查看:134
本文介绍了使用Knockout组件时替换容器元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法将淘汰赛组件配置为替换容器元素而不是将其内容嵌套在容器元素中?

Is there a way to configure a Knockout component to replace the container element instead of nesting its content inside the container element?

例如,如果我有一个自定义组件注册为 my-自定义元素,包含以下模板:

For example, if I have a custom component registered as my-custom-element with the following template:

<tr>
    <p>Hello world!</p>
</tr>

是否可以使用这样的组件:

Is it possible to use the component like this:

<table>
    <tbody>
        <my-custom-element></my-custom-element>
    </tbody>
</table>

最终产品为:

<table>
    <tbody>
        <tr>
            <p>Hello world!</p>
        </tr>
    </tbody>
</table>

而不是:( Knockout默认渲染组件的方式)

Instead of this: (the way Knockout renders components by default)

<table>
    <tbody>
        <my-custom-element>
            <tr>
                <p>Hello world!</p>
            </tr>
        </my-custom-element>
    </tbody>
</table>

基于关于这个问题的答案,似乎这个功能内置在模板引擎中,我假设在渲染组件模板时也会使用它。

Based on the answer to this question, it seems that this functionality is built into the templating engine, which I'm assuming is also used when rendering component templates.

有没有办法指定组件应该使用 renderMode replaceNode

Is there a way to specify that a component should be rendered with a renderMode of replaceNode?

我知道虚拟元素语法,它允许在HTML注释中定义组件:

I'm aware of the "virtual element" syntax, which allows components to be defined inside an HTML comment:

<table>
    <tbody>
        <!--ko component { name: 'my-custom-element' }--><!--/ko-->
    </tbody>
</table>

但我真的不喜欢这种语法 - 在评论中编写真实代码感觉就像一个肮脏,肮脏的黑客。

but I really dislike this syntax - writing real code inside a comment feels like a dirty, dirty hack.

推荐答案

我认为考虑到图书馆的性质,可以捍卫这个选项的缺乏(那里,我说过),以及开发人员的团队理念:

I imagine the lack of this option could be defended as such, considering the nature of the library (there, I said it), and the developer's team philosophy:

Knockout是一个库,与其他MVC不同,它不会强迫您使用框架定义的方式来构建应用程序。如果您考虑Knockout中的模板引擎与几乎所有其他JS模板引擎(在Angular,下划线,小胡子等中), Knockout是唯一一个不修改本机HTML5渲染的引擎。所有其他人都使用自定义标记,无论是< %%> 还是 {{}} 这需要一个小标签JS解析器将标签转换为有意义的东西(现在KO还有一个 Knockout punches 插件,其中包括小胡子风格的标签,并且不可否认,KO在<! - ko - > 评论中确实犯了一小撮。 KO改为使用HTML 5自定义元素,注释和属性标签,完全vanilla


例如,JS / DOM类型的'对象(和现实生活)使用?)层次结构':只有父母可以强行对孩子施加权力,因此绑定元素不会被替换,而是会被子项放大。例如:

Knockout is a library and unlike other MVC's it does not force you to use a framework-defined way to structure your application. If you consider the template engine in Knockout vs. virtually all other JS templating engines (in Angular, underscore, mustache, etc.), Knockout comes out as the only one not 'modding' native HTML5 rendering. All others use a custom tag, be it <% %> or {{ }} which requires a small JS parser to transform the tags into something meaningful (now KO also has a Knockout punches plugin which includes the mustache-style tags, and admittedly KO does 'sin' a small bit with <!-- ko --> comments). KO instead uses HTML 5 custom elements, comment and attribute tags, completely "vanilla".

For instance, the JS/DOM type of 'object (and real life?) hierarchy' is used: only parents can ever exerce power on their children, and so the bound-to element is not replaced, but enlarged with children. For illustration:

// we cannot do this in JS
document.getElementById('elem').remove(); //implied .remove(self)
// instead we do this
var elem = document.getElementById('elem');
container = elem.parentNode.removeChild(elem);

随后,与KO数据绑定的首选方式,由 foreach 绑定,是:

Subsequently, the preferred way of data-binding with KO, illustrated well by the foreach binding, is:

<div data-bind="foreach: myList">
  <span data-bind="text: $data"></span>
</div>

上一个片段是JS数组的HTML表示形式,层次结构再次可见:

The previous snippet being an HTML representation of a JS array, the hierarchy is visible again:

var myArr = [1,2,3,4,5];
// we cannot do the following without reference to the array index, 
// which is not held by the object itself,     
// but a meta-property getting meaning relative to the parent
myArr[0].splice(0,1); //remove

这会导致HTML视图成为JS数据的完美复制(它会有趣的是,有人建立一个工具,显示数据绑定缩进级别( foreach ) HTML文档。但是,在某些情况下,您需要注释标记,以便不破坏HTML的布局或css规则(嵌套),例如仅文本组件(i18n)在文本节点之间注入:

This leads to your HTML view being a perfect replication of your JS data (and it would be interesting to see someone build a tool that shows the data-bind indentation levels (with with and foreach) in an HTML document. In some cases however, you need comment tags, so as to not break the lay-out of your HTML, or your css rules (nesting), for example a 'text-only' component (i18n) that is to be injected between text nodes:

<p>Some predefined text with
<!-- ko text: 'some variable text' --><!-- /ko -->
and more predefined text</p>

或者当你不希望空元素在隐藏时占用空间

Or when you don't want an empty element to take up space when hidden

<!-- ko if: !hidden() --><div id="myToggleableDiv"></div><!-- /ko -->

然后有自定义标签,它们是标准化的,并且更加清晰;但遗憾的是还没有100%准备好。首先选择 data-bind <! - ko - > 秒,< custom> third(如果完全实现则会更高)。无论如何,这就是我的看法。至于您的具体情况,如果您的组件包含列表模型,您可以执行以下操作:

And then there are custom tags, which are standardized and a hell of a lot clearer; but unfortunately not a 100% ready yet. Choose data-bind first, <!-- ko --> second, and <custom> third (would be higher if fully implemented). That's how I see it, anyway. As for your specific case, if your component holds a list model, you could do:

<table data-bind="{component: {name: 'custom', params {..}}"></table>

并在VM中包含 tbody ,否则,如果它是listitem模型,您可以使用三种语法中的任何一种,例如注释语法

And include the tbody in your VM, else if it is a listitem model, you can use either one of the three 'syntaxes', eg the comment syntax

<table>
  <tbody data-bind="foreach: mylist">
    <!-- ko component: {name: 'custom', params: $data} --><!-- /ko -->
  </tbody>
</table>

或者将您的组件完全脱离嵌套在特定父(表)内的要求,坚持 SOC原则,例如:

Or decouple your component completely from the requirement of being nested inside a specific parent (table), adhering to the SOC principle, eg:

<table>
  <tbody data-bind="foreach: mylist">
    <tr data-bind="foreach: properties">
      <td data-bind="component: {name: 'custom', params: $data}></td>
    </tr>
  </tbody>
</table>

或使用自定义标记:

<table>
  <tbody data-bind="foreach: mylist">
    <tr data-bind="foreach: properties">
      <td><custom params= "{data: myData"></custom></td>
    </tr>
  </tbody>
</table>

按顺序偏好..

这篇关于使用Knockout组件时替换容器元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆