【问题标题】:Create new KO.observable array and populate it from an array object创建新的 KO.observable 数组并从数组对象中填充它
【发布时间】:2018-12-28 07:55:34
【问题描述】:

是否可以创建一个ko.observable 数组并使用数组对象填充它?

我的目标是创建一个 ko.observable 数组,其中包含原始数组中的所有描述/对象。

//Sample data the original data is coming from an socket query and being push on the array("people")
var people = [{
    name: "Contact 1",
    address: "1, a street, a town, a city, AB12 3CD",
    tel: "0123456789",
    email: "anemail@me.com",
    type: "family"
  },
  {
    name: "Contact 2",
    address: "1, a street, a town, a city, AB12 3CD",
    tel: "0123456789",
    email: "anemail@me.com",
    type: "friend"
  }
];.

var people = [{
    name: "Contact 1",
    address: "1, a street, a town, a city, AB12 3CD",
    tel: "0123456789",
    email: "anemail@me.com",
    type: "family"
  },
  {
    name: "Contact 2",
    address: "1, a street, a town, a city, AB12 3CD",
    tel: "0123456789",
    email: "anemail@me.com",
    type: "friend"
  }
];

var quotesarray = function(items) {
  this.items = ko.observableArray(items);
  this.itemToAdd = ko.observable("");
  this.addItem = function() {
    if (this.itemToAdd() != "") {
      this.items.push(this.itemToAdd());
      this.itemToAdd("");
    }
  }.bind(this);
};
ko.applyBindings(new quotesarray(people));

console.log(people);

【问题讨论】:

  • 你几乎可以做到,你遇到了什么问题?
  • @supercool 结果不敌
  • 你介意保留代码并显示错误我可以帮你修补它。
  • @supercool jsfiddle.net/zo8ygfk4/4这里我只是做一个简单的
  • 你应该遍历项目的 (jsfiddle.net/zo8ygfk4/7) 。 ko.applyBindings 将第一个参数作为 viewModel。由于您在第二个中没有提及任何参数,因此默认情况下它需要文档。

标签: javascript arrays knockout.js


【解决方案1】:

您只需将其设为 items 而不是 quotesarray

var people = [
    { name: "Contact 1", address: "1, a street, a town, a city, AB12 3CD", tel: "0123456789", email: "anemail@me.com", type: "family" },
    { name: "Contact 2", address: "1, a street, a town, a city, AB12 3CD", tel: "0123456789", email: "anemail@me.com", type: "friend" }
];


var quotesarray = function(items){
    this.items = ko.observableArray(items);
    this.itemToAdd = ko.observable("");
    this.addItem = function(){
        if (this.itemToAdd() != ""){
            this.items.push(this.itemToAdd());
            this.itemToAdd("");
        }
    }.bind(this);
};
ko.applyBindings(new quotesarray(people));

console.log(people);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<table>
    <thead>
        <tr><th>name</th><th>address</th></tr>
    </thead>
    <tbody data-bind="foreach: items">
        <tr>
            <td data-bind="text: name"></td>
            <td data-bind="text: address"></td>
        </tr>
    </tbody>
</table>

【讨论】:

  • 谢谢,但这适用于静态数组,但它不适用于我的代码,因为它来自套接字我总是遇到这个错误 Uncaught Error: You cannot apply bindings multiple times to the same element.
【解决方案2】:

您可以创建一个observableArray,套接字将消息写入该observableArray。你subscribe 到数组时会在内容发生变化时自动得到通知(即在套接字每次写入之后)。

subscribe 回调中,您清空数组并将项目添加到视图模型的属性中。

如果您希望收到许多快速后续的消息,您可以rateLimit 您写入的数组,以确保您不会多次更新 DOM。

这是一个例子。解释在代码cmets中。

const UPDATE_EVERY_MS = 500;

// The observable array the socket writes to
const received = ko.observableArray([])
  // Use a rateLimit extension if you expect to
  // receive many updates from your socket
  .extend({ rateLimit: UPDATE_EVERY_MS });
  
// The observable array in your viewmodel
const rendered = ko.observableArray([]);

received.subscribe(items => {
  // Write "inbox" to viewmodel's list
  rendered(rendered().concat(items));
  
  // Clear received without triggering notification
  items.length = 0;
});

ko.applyBindings({ items: rendered });


// Mock a socket that writes to `received`
setInterval(() => received.push(Math.random()), 200);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<ul data-bind="foreach: rendered">
  <li data-bind="text: $data"></li>
</ul>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-14
    • 1970-01-01
    • 2020-01-26
    • 2020-07-26
    • 2017-03-22
    • 2021-08-12
    • 1970-01-01
    • 2021-07-03
    相关资源
    最近更新 更多