geoko93
geoko93

Reputation: 45

Objects in observablearray KnockoutJs

Using SignalR I send to the client an array of objects with this structure

Url = s.Piece.Name,
Id = s.Id,
IsLighted = s.IsLighted,
Class = s.ColorType

The array in javascript is like this

self.CellList = ko.observableArray([]);

It starts as blank and when a server function is called it fills like this

function updateBoard(cellList) {
    viewModel.CellList.removeAll();
    for (var i = 0; i < cellList.length; i++) {
            viewModel.CellList.push(cellList[i]);
    }
};

Is it possible that in the cshtml page like this?

CellList()[77].Url

Upvotes: 0

Views: 94

Answers (1)

kasperoo
kasperoo

Reputation: 1584

If you mean, can how can you show the results of observable array in your view, then there's few ways to go on about that:

var data = [{
  Url: 's.Piece.Name',
  Id: 's.Id',
  IsLighted: 's.IsLighted',
  Class: 's.ColorType'
}, {
  Url: 's.Piece.Name2',
  Id: 's.Id2',
  IsLighted: 's.IsLighted2',
  Class: 's.ColorType2'
}];

var DemoPage = (function() {
  function DemoPage() {
    var self = this;
    self.CellList = ko.observableArray([]);
    self.updateBoard = function(cellList) {
      var _temp = [];
      for (var i = 0; i < cellList.length; i++) {
        // I've created a temporary array here, so knockout won't 
        // re-draw every time you push, then when we finally finish this loop
        // it's pushed to the right target
        _temp.push(cellList[i]);
      }
      self.CellList(_temp);
    }
  }

  return DemoPage;
})();

var demo = new DemoPage();

ko.applyBindings(demo);

demo.updateBoard(data);
.result p {
  color: teal
}
.result {
  margin-top: 11px;
  border-top: 1px solid #bbb;
  padding-top: 11px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<p>Display individual item:</p>

<!-- ko if: CellList().length > 0 -->
<p data-bind="text: CellList()[0].Url"></p>
<!-- /ko -->

<p>Or just loop them:</p>
<!-- ko if: CellList().length > 0 -->
<div data-bind="foreach: CellList">
  <div class="result">
    <p data-bind="text: Url"></p>
    <p data-bind="text: Id"></p>
    <p data-bind="text: IsLighted"></p>
    <p data-bind="text: Class"></p>
  </div>
</div>
<!-- /ko -->

Notice that I've wrapped them with virtual if bindings - that's because on the initialization, the array is empty and there are no objects with those properties at that time. Only show them when there's at least 1 element in the array.

You could also use mapping, and convert all object properties into observables, then they all could be changed dynamically later.

Upvotes: 1

Related Questions