【问题标题】:How to pass observableArray to template using data如何使用数据将 observableArray 传递给模板
【发布时间】:2019-06-04 04:36:20
【问题描述】:

我正在尝试将 observableArray 传递给模板:

<template id="my-template">
    <pre data-bind="text: JSON.stringify($data)"></pre>
    <!-- prints: { isWarning: false } --/>
</template>


<div data-bind="template: { name: my-template, data: { errors: myObservableArray, isWarning: false }}"></div>

看起来 observableArray 不能作为数据传递。我尝试用() 调用它:

template: { 
   name: my-template, 
   data: { errors: myObservableArray(), isWarning: false }
}

这打印{ errors: [], isWarning: false }

但是我想将 ObservableArray,而不是 Array 传递给模板。

不改JS可以吗?

【问题讨论】:

  • 您传递的模板名称不带引号,这可能是问题的根源吗?实际上,其他一切似乎都还好,你应该能够传递一个像这样的可观察数组(不带括号),然后在你的模板中像 observableArray 一样使用它,而不是简单的 JS 数组。您也可以在这里发布您在第一个变体中得到什么吗?您在控制台中遇到错误吗?如果是这样,请在此处发布

标签: javascript knockout.js knockout-3.0


【解决方案1】:

observableArray 已正确传递给模板。不打印的原因是JSON.stringify 为淘汰的可观察对象返回未定义,它没有在pre 元素中呈现。要使示例工作,请改用ko.toJSON。看看下面的sn-p:

ko.applyBindings({ 
  myObservableArray: ko.observableArray(['error 1', 'error 2', 'error 3'])
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>

<template id="my-template">
  <!-- ko foreach: errors -->
  <span data-bind="text: $data"></span>
  <!-- /ko -->
  <pre data-bind="text: ko.toJSON($data)"></pre>
</template>


<div data-bind="template: { name: 'my-template', data: { errors: myObservableArray, isWarning: false }}"></div>

【讨论】:

  • 这确实是一种非常奇怪的行为。只是出于好奇,你知道为什么 JSON.stringify 会返回 undefined 用于淘汰 observables 吗?这怎么可能?
  • 好问题。我的假设是,knout 在 observables 上实现了一个 toJSON 方法,spec 负责序列化,但我在 knout 源中找不到它。也不知道他们为什么会返回 undefined ......返回 ko.toJSON 的结果会更有意义。
  • 我不知道toJSON 函数被JSON.stringify 调用。有趣...
【解决方案2】:

我猜这是您的binding context 的问题。我经常发现在开发期间关闭&lt;/body&gt; 标记之前立即留下以下调试sn-p 非常宝贵,在部署期间删除/注释掉。这将显示关于您的应用程序的所有淘汰赛“知道”,特别是传递给.applyBindings(...) 的内容。特别重要的是价值层次。

<pre data-bind="text: ko.toJSON($root)"></pre>

您正在尝试做的事情绝对是可能的。这是一个example 演示了这一点。记下$data.myObservableArray。这里$data的用法是从当前绑定上下文中请求值。

作为一个架构建议,我建议在几乎所有情况下都偏爱components 而不是模板。它们提供了更高的可重用性、异步处理和关注点分割。

【讨论】:

    【解决方案3】:

    您的代码几乎是完美的,我只是将模板名称放在 '' 中并用 () 传递您的数组以传递评估值,它起作用了。

    function VM(){
    var self = this;
    self.myObservableArray = ko.observableArray(["error1","error2","error3","error4","error4"]);
    self.isWarning = ko.observable(false);
    }
    
    ko.applyBindings(new VM())
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <template id="my-template">
        <pre data-bind="text: JSON.stringify($data)"></pre>
    </template>
    
    
    <div data-bind="template: { name: 'my-template', data: { errors: myObservableArray(), isWarning: isWarning() }}"></div>

    【讨论】:

    • 我不想用 () 传递我的数组,我需要传递 observableArray,因为在我的真实模板中我有 foreach 绑定,我需要它来反映更改。
    • 你能提供你想要实现的实际模板绑定吗?它看起来像 template: { name: 'my-template', foreach: myObservableArray }
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-26
    • 1970-01-01
    • 2019-12-17
    • 2012-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多