是否推送到具有具体对象的可观察数组?

Push to observable array with concrete object or not?

这是怎么回事:

var Tag = function (data) {
    this.name = ko.observable(data.name);
}

//////

self.tags.push(new Tag({name: self.newTagName()}));

与此不同:

self.tags.push({name: self.newTagName()});

我从教程中选择了第一个,然后开始学习击倒,但它让我感到困惑,我已经找到了第二个选项的逻辑。

第一个有什么优点?

好吧,当进入推送部分时,两者是相同的,但两者之间存在很大差异,因为您在案例 1 中推送 observable,而在其他情况下,您试图为 name

从性能角度来看,我认为这没有什么不同。 Case-1 是可读和可维护的。

查看:

Type 1: Not a observable (Two way binding doesn't exist)
<div data-bind="foreach:tags1">
    <input type="text" data-bind="value:name" />
</div>

Type 2:  Observable ( Two way binding )
<div data-bind="foreach:tags2">
    <input type="text" data-bind="value:name" />
</div>

ViewModel:

var vm =  function(){
var self=this;
self.tags1=ko.observableArray();
self.newTagName=ko.observable('Hi there');
self.tags1.push({name: self.newTagName()}); //you just pushing plane text

var Tag = function (data) {
 this.name = ko.observable(data.name);
}

self.tags2=ko.observableArray();
self.tags2.push(new Tag({name: self.newTagName()}));    
}

ko.applyBindings(new vm());

工作fiddlehere

快速修复使第一个案例工作像这样self.tags1.push({name: ko.observable(self.newTagName())})

基本上 只有当视图模型的状态 属性 是动态的并且响应用户 'input'(事件) 时才会使用可观察对象。例如,如果您有一个带有向上、向下、添加和删除按钮的列表工具栏,您可以在视图模型中包含以下 JS:

this.toolbar = [
  {name: 'add', action: this.add, icon: 'plus'},
  {name: 'remove', action: this.remove, icon: 'close'},
  {name: 'up', action: this.moveUp, icon: 'arrow-up'},
  {name: 'down', action: this.moveUp, icon: 'arrow-down'}
];

以及以下HTML:

<span data-bind="foreach: toolbar">
  <button type="button" data-bind="attr: { title: name }, click: action">
    <i data-bind="attr: { class: 'fa fa-' + icon}"></i>
  </button> 
</span>

IE以前的UI只需要单向绑定(model=>view);按钮不会改变。 但是,假设我们要添加一个按钮来打开/关闭每个列表项的详细信息。这个按钮有一个状态:打开或关闭。为此,我们需要在按钮对象中添加一个包含布尔值的可观察对象。我们还想在 open/close 上将图标从 + 更改为 -,反之亦然,因此 'icon' 在这里将是计算的 属性,如下所示:

var toggleButton = {name: 'toggle'};
toggleButton.state = ko.observable(false); // closed by default
toggleButton.action = function() { toggleButton.state(!toggleButton.state()); };
toggleButton.icon = ko.computed(function() {
    return toggleButton.state() ? 'minus' : 'plus';});
this.toolbar.push(toggleButton);

和修改后的HTML:

<span data-bind="foreach: toolbar">
  <button type="button" data-bind="attr: { title: name }, click: action">
    <i data-bind="attr: { class: 'fa fa-' + ko.unwrap(icon) }"></i>
  </button> 
</span>

至于 "what are the pros of regular objects/properties":它们是静态的,因此您可以将它们用于例如创建后永不更改的唯一 "ID" 属性。在性能方面,只有当一个可观察数组包含许多具有许多可观察属性的项目时,我才会遇到一些麻烦。

当你的对象需要它们自己的作用域,或者如果你有很多对象来共享原型方法,甚至自动化 JSON 数据映射时,使用构造函数很方便(相对于对象文字)。

var app = function() {
    this.add = this.remove = this.moveUp = this.moveDown = function dummy() { return; };
    this.toolbar = [
      {name: 'add', action: this.add, icon: 'plus'},
      {name: 'remove', action: this.remove, icon: 'close'},
      {name: 'up', action: this.moveUp, icon: 'arrow-up'},
      {name: 'down', action: this.moveUp, icon: 'arrow-down'}
    ];
    var toggleButton = {name: 'toggle'};
    toggleButton.state = ko.observable(false); // closed by default
    toggleButton.action = function() { toggleButton.state(!toggleButton.state()); };
    toggleButton.icon = ko.computed(function() { return toggleButton.state() ? 'minus' : 'plus';});
    this.toolbar.push(toggleButton);
}
ko.applyBindings(new app());
.closed { overflow: hidden; left: -2000px; }
.open { left: 0; }
div { transition: .3s all ease-in-out; position: relative;}
<link href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<i>( only the last (toggle) button working for demo )</i>
<span data-bind="foreach: toolbar">
      <button type="button" data-bind="attr: { title: name }, click: action">
        <i data-bind="attr: { class: 'fa fa-' + ko.unwrap(icon) }"></i>
      </button> 
</span>
<h4>Comments</h4>
<div data-bind="css: { 'open': toolbar[4].state, 'closed': !toolbar[4].state() }">
Support requests, bug reports, and off-topic comments will be deleted without warning.

Please do post corrections and additional information/pointers for this article below. We aim to move corrections into our documentation as quickly as possible. Be aware that your comments may take some time to appear.

If you need specific help with your account, please contact our support team.
</div>