【问题标题】:Dynamic amount of observables with knockout.js带有 knockout.js 的可观察对象的动态数量
【发布时间】:2014-12-10 13:33:32
【问题描述】:

我有一个与 knockout.js 库相关的基本问题。

到目前为止,我正在创建一些数字和范围类型的输入字段。

<input type="range" min="0.0" max="1.0" step="0.001" data-bind="value: example1" ></input>
<input type="number" min="0.0" max="1.0" step="0.001" data-bind="value: example1"></input>

<input type="range" min="0.5" max="2.5" step="0.001" data-bind="value: example2" ></input>
<input type="number" min="0.5" max="2.5" step="0.001" data-bind="value: example2"></input>

激活 knockout.js 时,我只是在做类似的事情

this.example1 = ko.observable("0.000");
this.example2 = ko.observable("0.000");

我的问题是网站会随机接收这些输入参数。对于某些项目,在我的示例中只有 2 个,而其他项目则采用 8 个参数。

如何在淘汰赛中指定这些 observables 的动态数量?

谢谢!


编辑:

解决了。

继续选择答案的解决方案:

通过“attr”绑定,我能够为每个输入设置不同的属性值。

<input type="number" step="0.001" data-bind="value: value, attr: {id: name, min: minValue, max: maxValue}"></input>

【问题讨论】:

  • 您的编辑(带有解决方案)几乎与您的问题无关。您的问题询问如何拥有一个具有可变数量的可观察对象的视图模型,但您的解决方案详细说明了您如何绑定数据的 HTML 属性。
  • 我的编辑是为了延续所选答案的解决方案。它可能会帮助面临相同问题并偶然发现有关如何将此解决方案与数据绑定 HTML 属性一起使用的问题。

标签: javascript html arrays dynamic knockout.js


【解决方案1】:

只需使用可观察的可观察数组即可。创建一个 observable 数组,并为服务器返回的每个结果 .push() 将一个新的 observable 或带有 observables 的对象放入 observable 数组中。

然后在 Dom 中使用 for each 绑定来遍历它们并显示每一个。

在虚拟机中 -

var objectsArray = ko.observableArray();

// results from AJAX or w/e
ko.utils.arrayForEach(results, function (result) {
    objectsArray.push(new ObjectType(result));
});

function ObjectType (data) {
    var self = this;
    self.SomeProperty = ko.observable(data);
}

然后在视图中

<div data-bind="foreach: objectsArray">
    <input data-bind="value: SomeProperty " />
</div>

jsFiddle 示例 -

http://jsfiddle.net/zabpe3jm/

【讨论】:

  • 呃...你不是刚刚编辑了你的答案,让它看起来像我的一样糟糕吗?
  • rofl - 我在你之前用手机接了电话,我不得不回来在我的电脑上添加代码示例。相信我,我没有看你的答案,谢谢
  • 谢谢,这很好用,我只需要了解“attr”绑定即可为每个输入获取不同的属性值。
  • 这个答案没有错误吗?视图模型有一个名为 SomeProperty 的可观察对象,而 HTML 示例调用了一个名为 $data 的可观察对象。
  • @awj Fiddle 有效,如果您觉得有错误,请随时提出修改建议。
【解决方案2】:

一方面,JavaScript 使得在需要时向对象添加属性变得相当容易,因此拥有一个准确反映您的数据的视图模型并不难。

另一方面,棘手的部分是具有data-bind 属性的 HTML,这将准确反映您的动态视图模型。

一种可能的解决方案是将您的视图模型重构为两个:

function viewModelContainer(arrData) {

    var self = this;

    // this holds a dynamic number of elements, depending upon the data from the server
    self.Observables = ko.observableArray([]);

    // using an IIFE as a type of constructor for getting the 
    // `arrData` param into your observable
    (function(arrData) {
        // add all elements in a single call so that you don't cause
        // multiple unnecessary updates to the UI
        var arr = [];
        for (var i = 0, iMax == arrData.length; i < iMax; i++) {
            arr.push(new viewModelData(arrData[i]));
        }
        self.Observables.push(arr);
    }(arrData));
}


function viewModelData(data) {

    var self = this;

    self.Data = ko.observable(data);
}

所以现在你有一个对象/视图模型(viewModelContainer 的一个实例),它知道它包含多少个值。

下一步是在您的 HTML 中枚举这些(使用 Knockout):

<!-- ko foreach: Observables -->
    <input type="range" min="0.0" max="1.0" step="0.001" data-bind="value: Data" ></input>
    <input type="number" min="0.0" max="1.0" step="0.001" data-bind="value: Data"></input>
<!-- /ko -->

我是凭记忆写的徒手,所以你可能需要润色它,但我希望你能明白要点。

【讨论】:

    【解决方案3】:

    我认为您不想使用observable,而是使用observableArray

    this.yourObjects = ko.observableArray([]);
    

    然后,假设您有一些包含输入参数的源数组,您只需将它们添加到数组中:

    for (var i in sourceArray) {
        this.yourObjects.push(sourceArray[i]);
    }
    

    要渲染它,只需使用 foreach 绑定:

    <div data-bind="foreach: yourObjects">
        <input type="range" min="0.0" max="1.0" step="0.001" data-bind="value: $data" ></input>
    </div>
    

    请注意,您使用“value: $data”是因为您不想要项目的某些属性,而是项目本身(如您的数字值)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-01-30
      • 2015-10-23
      • 1970-01-01
      • 2019-09-09
      • 2015-02-06
      • 2019-12-16
      • 2018-11-26
      相关资源
      最近更新 更多