【问题标题】:Can a field initialized to an observable object become an array in knockout.js?初始化为 observable 对象的字段能否成为 knockout.js 中的数组?
【发布时间】:2014-09-23 01:56:44
【问题描述】:

我正在阅读现有代码。最初,代码初始化属性“数据”:

self.Data = ko.observable({});

但之后,在某些函数中,代码将“数据”分配给如下所示的内容。 self.Data 未设置为 observableArray,但在下面,它通过数组原样使用。在这一行之前没有其他代码触及 self.Data,所以当它到达这一行但在赋值之前,它仍然是一个 ko.observable({})。

self.Data()[0] = ko.observable("");

我在想这是在 knockout.js 中将可观察对象转换为数组的合法语法,但如果我尝试立即对其长度发出警报,如 alert(self.Data().length),它未定义。

我的问题是这段代码实际上是做什么的?

【问题讨论】:

  • 我不确定 self.Data = ko.observable({});是 observable 的有效语法。我通常会以这种方式初始化一个 observableArray

标签: knockout.js


【解决方案1】:

它不是一个可观察的数组。它是一个对象。使用 javascipt 对象,您可以通过点表示法或索引表示法访问它的属性。 link

由于 javascript 是动态类型的,您可以向现有对象添加新属性。

下面的代码实际上只是为现有的对象实例添加了一个新的 observable 属性。

self.Data()[0] = ko.observable("");

下面是一个示例,希望能帮助您了解正在发生的事情。

var vm = function(){
  var self = this;
  self.data = ko.observable({});
  self.dataString = ko.computed(function(){return JSON.stringify(self.data(), null, 2);});

  self.propertyName = ko.observable(0);
  self.propertyValue = ko.observable('someValue');

  self.update = function(){
    //This adds a new property or updates an existing property of the object the self.data observable references.
    //The name of the property will be the value of the self.propertyName observable which will be the value typed into the first textbox in the UI.
    //The value of the property will be the value of the self.propertyValue observable which will bhe the value typed into the second textbox in the UI.
    self.data()[self.propertyName()] = self.propertyValue();
    //Need to force an update since the data observable wasn't directly modified
    self.data.valueHasMutated(); 
  };
  
  self.replace = function(){
    //Replace the existing value with a new object
    var data = {};
    data[self.propertyName()] = self.propertyValue();
    self.data(data);
  };
}

$().ready( function(){
  ko.applyBindings(new vm());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

Property Name <input data-bind="textInput:propertyName" /> <br />
Property Value <input data-bind="textInput:propertyValue" /> <br />

<button data-bind="click:update">Update</button>
<button data-bind="click:replace">Replace</button><br />
The self.data observable represented as a json string:
<pre data-bind="text:dataString"></pre>

【讨论】:

  • 嗨亚伦,对不起,我有点困惑。根据您给我的链接,您可以使用索引表示法在 JavaScript 中动态添加属性。但是在我的示例(和您的示例)中,我似乎无法弄清楚 data 的新属性名称是什么。谢谢。
  • 等等,我想您是说在您的示例 self.data()[self.propertyName()] 中,属性名称是一个可观察对象?还是只是新属性是一个可观察的对象?没有属性名称?在我的例子中怎么样?
  • 这不是数据的新属性名,而是添加到数据可观察对象引用的对象中的名为 0 的属性。
  • self.data()[self.propertyName()] 并不意味着属性名称是可观察的。 self.propertyName() 将 observable 拆箱并返回底层值。在这种情况下,它将是在 ui 的第一个文本框中输入的任何内容。
猜你喜欢
  • 2019-11-05
  • 2020-10-13
  • 1970-01-01
  • 2012-05-20
  • 1970-01-01
  • 2013-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多