用具体对象推送到可观察数组?

时间:2015-03-02 14:38:47

标签: javascript knockout.js

这是怎么回事:

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

//////

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

与此不同:

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

我拿起了第一篇教程并开始学习淘汰赛,但它让我很困惑,而且我已经将逻辑跟踪到了第二个选项。

第一个有什么优点?

2 个答案:

答案 0 :(得分:1)

当进入推动部分时两者都相同但两者之间存在很大差异,因为你在Case-1中推动observable,就像在其他情况下你尝试为{{1}分配值一样}。

绩效观点我不认为它会有所作为。案例1是可读和可维护的。

查看:

name

<强>视图模型:

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>

工作小提琴 here

快速修复以使第一个案例可以执行此类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());

答案 1 :(得分:1)

基本上只有当viewmodel属性的状态是动态的时才使用observable,并且响应用户&#39;输入&#39; (事件)即可。例如,如果您有一个带有向上,向下,添加和删除按钮的列表工具栏,您可以在viewmodel中使用以下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 =&gt; view);按钮不会改变。 但是,假设我们要添加一个按钮来打开/关闭每个列表项的详细信息。此按钮具有状态:打开或关闭。为此,我们需要添加一个observable,它在按钮对象中保存一个布尔值。我们还想将图标从+更改为 - ,反之亦然,打开/关闭,所以&#39; icon&#39;这里将是一个计算属性,如下所示:

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>

至于&#34;常规对象/属性的优点是什么&#34;:它们是静态的,所以你可以使用它们,例如,对于一个独特的&#34; ID&#34;创造后永不改变的财产。性能方面我只有在一个可观察数组包含许多具有许多可观察属性的项目时才遇到麻烦。

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

&#13;
&#13;
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());
&#13;
.closed { overflow: hidden; left: -2000px; }
.open { left: 0; }
div { transition: .3s all ease-in-out; position: relative;}
&#13;
<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>
&#13;
&#13;
&#13;