如何创建嵌套的可观察数组?

时间:2014-07-18 12:02:36

标签: knockout.js ko.observablearray

我正在使用HTML5,Knockouk和Jquery开发应用程序。

UI显示订单列表。首先它会显示5个订单,当用户点击"显示更多"按钮,接下来的5个订单将显示。

点击订单后,我会显示与该订单相关的所有活动,当用户点击"更多"时,我将显示前10个活动等等。按钮。

我根据要求创建了一个小例子。我创建了第一步,但我无法创建第2步。我不确定如何创建嵌套的可观察数组。我添加了一个样本,它正在为步骤而不是第二步。

<h1>Using Observable Arrays<br /></h1>

<div id="divActivites">
    <!-- ko foreach: Activities -->
        <div data-bind="click:$root.showDesc, attr:{'name':name,'id':id}">
            <td><span data-bind="text:name"></span></td>
            <td><span data-bind="text:id"></span></td>
        </div>
    <!-- /ko -->
    <input type="button" value="Show More" data-bind="click:addData" />
</div>
<div id="divActDec" data-bind="with:selectedData ">
    <span data-bind="text:id"></span><br />
    <span data-bind="text:name"></span><br />
    <span data-bind="text:randomStringDesc()"></span>

</div>

<script type="text/javascript">
function ActivityListModel() {
      var self = this;
      var total = ko.observable();
      self.Activities = ko.observableArray([]);
      self.selectedData = ko.observable();

      total = 0;

      self.addData = function () {
          var addtoArray = 5;

          var finalVal = total + addtoArray;

          for (var i = total+1; i <= finalVal; i++) {
              self.Activities.push(
              {
                  name: randomString(),
                  id: i
              }
              )
          }

          total = finalVal;
      }

      self.showDesc = function (ActivitiesDesc) {
          $("#divActivites").hide();
          $("#divActDec").show();
          self.selectedData(ActivitiesDesc);
      }
  }

  function ActivitiesDesc(data) {
      var activitydesc = this;
      activitydesc.name = data.name;
      activitydesc.actid = data.id;
  }

  function randomString() {
      var value = "";
      var letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
      for (var i = 0; i < 10; i++) {
          value += letters.charAt(Math.floor(Math.random() * letters.length));
      }
      return value;
  }

  function randomStringDesc() {
      var value = "";
      var letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
      for (var i = 0; i < 150; i++) {
          value += letters.charAt(Math.floor(Math.random() * letters.length));
      }
      return value;
  }

  ko.applyBindings(new ActivityListModel());
</script>

有人可以告诉我如何将ActivitiesDesc对象创建为可观察数组吗?

谢谢, Jollyguy

1 个答案:

答案 0 :(得分:1)

这是我认为你之后的工作版本:

Working JS Fiddle

首先,我将详细信息部分嵌套到foreach块中,并创建了一个observable来控制它的可见性showDesc,并修改了click绑定以调用toggleDesc },打开或关闭可见性:

<!-- ko foreach: Activities -->
<div data-bind="click:$root.toggleDesc, attr:{'name':name,'id':id}">
    <div>Name: <span data-bind="text:name"></span>

    </div>
    <div>Id: <span data-bind="text:id"></span>

    </div>
</div>
<!-- added this block with a visible binding -->
<div id="divActDec" data-bind="visible: showDesc" 
                    style="border: 1px solid #000;">
     <h1>Details:</h1>
     ID: <span data-bind="text:id"></span><br />
     Name: <span data-bind="text:name"></span><br />
     Desc: <span data-bind="text:randomStringDesc()"></span>

</div>
<!-- /ko -->

在JS中,每个Activity会看到一个新的observable,如下所示:

showDesc: ko.observable(false)

默认设置为false。然后是单击项目时切换说明的方法:

self.toggleDesc = function (item) {
    item.showDesc(!item.showDesc());
}

完整的JS

function ActivityListModel() {
    var self = this;
    var total = ko.observable();
    self.Activities = ko.observableArray([]);
    self.selectedData = ko.observable();

    total = 0;

    self.addData = function () {
        var addtoArray = 5;

        var finalVal = total + addtoArray;

        for (var i = total + 1; i <= finalVal; i++) {
            self.Activities.push({
                name: randomString(),
                id: i,
                showDesc: ko.observable(false)
            })
        }

        total = finalVal;
    }

    self.toggleDesc = function (item) {
        item.showDesc(!item.showDesc());
    }
}

function ActivitiesDesc(data) {
    var activitydesc = this;
    activitydesc.name = data.name;
    activitydesc.actid = data.id;
}

function randomString() {
    var value = "";
    var letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    for (var i = 0; i < 10; i++) {
        value += letters.charAt(Math.floor(Math.random() * letters.length));
    }
    return value;
}

function randomStringDesc() {
    var value = "";
    var letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    for (var i = 0; i < 150; i++) {
        value += letters.charAt(Math.floor(Math.random() * letters.length));
    }
    return value;
}

ko.applyBindings(new ActivityListModel());

<强>更新

我已将示例更新为将observableArray嵌套到顶级数组中。我已将顶级数组重命名为Orders,现在包含activities数组:

Updated JS Fiddle:

for循环现在看起来像这样:

    for (var i = total + 1; i <= finalVal; i++) {
        self.Orders.push({
            name: randomString(),
            id: i,
            showDesc: ko.observable(false),
            activities: ko.observableArray([{
                "name": "Description 1",
                "actid": 123
            }, {
                "name": "Description 2",
                "actid": 456
            }])
        })