如何迭代 Knockout ObservableArray? (长度为 0)
How to iterate an Knockout ObservableArray? (length 0)
我是 knockout.js 的新手(这也是我的第一个 Whosebug post),我现在面临以下问题。
我无法将来自 Web api 的数据绑定到 ko.observablearray。为什么这个公告ko.observablearray的长度总是0?该代码适用于客户端数据(通过添加新公告)..
这是 JS 代码:
var AnnouncementModel = function () {
var self = this;
self.AnnouncementText = ko.observable();
self.AllDepartmentsBool = ko.observable();
self.Editable = ko.observable(false);
self.Add = function () {
viewModel.Announcements.push(self);
viewModel.AnnouncementToEdit(new AnnouncementModel());
};
self.Delete = function () {
ajaxHelper(announcementsUri + self.ID, 'DELETE').done(
viewModel.Announcements.remove(self));
};
self.Edit = function () {
self.Editable(!self.Editable());
};
}
//The ViewModel
function AnnouncementsViewModel() {
var self = this;
self.InitialData = ko.observableArray();
self.Announcements = ko.observableArray();
self.AnnouncementToEdit = ko.observable(new AnnouncementModel());
self.error = ko.observable();
function getAllAnnouncements() {
ajaxHelper(announcementsUri, 'GET').done(function(data) {
self.InitialData(data);
});
};
getAllAnnouncements();
};
var viewModel = new AnnouncementsViewModel();
ko.applyBindings(viewModel, document.getElementById("announcements-container"));
function createAnnouncement(announcementDto) {
var announcement = new AnnouncementModel();
announcement.AnnouncementText = ko.observable(announcementDto.AnnouncementText);
announcement.AllDepartmentsBool = ko.observable(announcementDto.AllDepartmentsBool);
announcement.Editable = ko.observable(false);
return announcement;
}
var length = viewModel.InitialData.length;
for (i = 0; i < length; i++) {
var newAnnouncement = createAnnouncement(InitialData[i]);
viewModel.Announcements.push(newAnnouncement);
}
HTML:
<div id="announcements-container" style="display: inline-block; float: right">
<ul id="announcements-list" class="newsticker" data-bind="foreach: Announcements">
<li>
<span data-bind="html: AnnouncementText"></span>
</li>
</ul>
@Html.Partial("_AnnouncementsModal")
</div>
InitialData 按原样从 api 填充:
成功了! :
感谢您的快速解答。我通过使用 .forEach() 迭代数据使代码工作。另一个问题是 initialData 没有在它的当前范围内填充,所以我编辑了 getAnnouncements 函数,使其像这样工作:
function getAllAnnouncements() {
ajaxHelper(announcementsUri, 'GET').done(function(data) {
data.forEach(function (entry) {
var newAnnouncement = createAnnouncement(entry);
self.Announcements.push(newAnnouncement);
});
});
};
这一行可能是罪魁祸首:
var length = viewModel.InitialData.length;
请记住 InitialData
是一个 函数 。函数有一个 length
(这是它们的 "arity",它们拥有的正式参数的数量),但是可观察数组的 length
的可观察函数不是数组的 length
。 .
您可能想要其中数组的长度:
var length = viewModel.InitialData().length;
// -------------------------------^^
您对可观察数组 push
的各种调用有效,即使 length
无效,因为 Knockout provides push
(and several other things) on the observable array function, as .
同样,这一行:
var newAnnouncement = createAnnouncement(InitialData[i]);
可能也想使用数组(并且在 InitialData
前面缺少 viewModel.
)。
所以整个部分可能需要重构一下:
viewModel.InitialData().forEach(function(entry) {
var newAnnouncement = createAnnouncement(entry);
viewModel.Announcements.push(newAnnouncement);
});
或没有 forEach
(但实际上,已经快 2016 年了,它可以在过时的浏览器上移动);
var data = viewModel.InitialData();
for (var i = 0; i < data.length; ++i) {
var newAnnouncement = createAnnouncement(data[i]);
viewModel.Announcements.push(newAnnouncement);
}
旁注:您的代码(至少在问题中如此)也因未声明您在 for
循环中使用的 i
而成为 The Horror of Implicit Globals 的牺牲品.我在上面添加了一个 var
,但这是使用 forEach
循环遍历数组的另一个原因。
您还可以使用 EcmaScript 6 风格的枚举,如下所示:
viewModel.InitialData().forEach(item => {
let newAnnouncement = createAnnouncement(item);
viewModel.Announcements.push(newAnnouncement);
});
我是 knockout.js 的新手(这也是我的第一个 Whosebug post),我现在面临以下问题。
我无法将来自 Web api 的数据绑定到 ko.observablearray。为什么这个公告ko.observablearray的长度总是0?该代码适用于客户端数据(通过添加新公告)..
这是 JS 代码:
var AnnouncementModel = function () {
var self = this;
self.AnnouncementText = ko.observable();
self.AllDepartmentsBool = ko.observable();
self.Editable = ko.observable(false);
self.Add = function () {
viewModel.Announcements.push(self);
viewModel.AnnouncementToEdit(new AnnouncementModel());
};
self.Delete = function () {
ajaxHelper(announcementsUri + self.ID, 'DELETE').done(
viewModel.Announcements.remove(self));
};
self.Edit = function () {
self.Editable(!self.Editable());
};
}
//The ViewModel
function AnnouncementsViewModel() {
var self = this;
self.InitialData = ko.observableArray();
self.Announcements = ko.observableArray();
self.AnnouncementToEdit = ko.observable(new AnnouncementModel());
self.error = ko.observable();
function getAllAnnouncements() {
ajaxHelper(announcementsUri, 'GET').done(function(data) {
self.InitialData(data);
});
};
getAllAnnouncements();
};
var viewModel = new AnnouncementsViewModel();
ko.applyBindings(viewModel, document.getElementById("announcements-container"));
function createAnnouncement(announcementDto) {
var announcement = new AnnouncementModel();
announcement.AnnouncementText = ko.observable(announcementDto.AnnouncementText);
announcement.AllDepartmentsBool = ko.observable(announcementDto.AllDepartmentsBool);
announcement.Editable = ko.observable(false);
return announcement;
}
var length = viewModel.InitialData.length;
for (i = 0; i < length; i++) {
var newAnnouncement = createAnnouncement(InitialData[i]);
viewModel.Announcements.push(newAnnouncement);
}
HTML:
<div id="announcements-container" style="display: inline-block; float: right">
<ul id="announcements-list" class="newsticker" data-bind="foreach: Announcements">
<li>
<span data-bind="html: AnnouncementText"></span>
</li>
</ul>
@Html.Partial("_AnnouncementsModal")
</div>
InitialData 按原样从 api 填充:
成功了! :
感谢您的快速解答。我通过使用 .forEach() 迭代数据使代码工作。另一个问题是 initialData 没有在它的当前范围内填充,所以我编辑了 getAnnouncements 函数,使其像这样工作:
function getAllAnnouncements() {
ajaxHelper(announcementsUri, 'GET').done(function(data) {
data.forEach(function (entry) {
var newAnnouncement = createAnnouncement(entry);
self.Announcements.push(newAnnouncement);
});
});
};
这一行可能是罪魁祸首:
var length = viewModel.InitialData.length;
请记住 InitialData
是一个 函数 。函数有一个 length
(这是它们的 "arity",它们拥有的正式参数的数量),但是可观察数组的 length
的可观察函数不是数组的 length
。 .
您可能想要其中数组的长度:
var length = viewModel.InitialData().length;
// -------------------------------^^
您对可观察数组 push
的各种调用有效,即使 length
无效,因为 Knockout provides push
(and several other things) on the observable array function, as
同样,这一行:
var newAnnouncement = createAnnouncement(InitialData[i]);
可能也想使用数组(并且在 InitialData
前面缺少 viewModel.
)。
所以整个部分可能需要重构一下:
viewModel.InitialData().forEach(function(entry) {
var newAnnouncement = createAnnouncement(entry);
viewModel.Announcements.push(newAnnouncement);
});
或没有 forEach
(但实际上,已经快 2016 年了,它可以在过时的浏览器上移动);
var data = viewModel.InitialData();
for (var i = 0; i < data.length; ++i) {
var newAnnouncement = createAnnouncement(data[i]);
viewModel.Announcements.push(newAnnouncement);
}
旁注:您的代码(至少在问题中如此)也因未声明您在 for
循环中使用的 i
而成为 The Horror of Implicit Globals 的牺牲品.我在上面添加了一个 var
,但这是使用 forEach
循环遍历数组的另一个原因。
您还可以使用 EcmaScript 6 风格的枚举,如下所示:
viewModel.InitialData().forEach(item => {
let newAnnouncement = createAnnouncement(item);
viewModel.Announcements.push(newAnnouncement);
});