如何循环的淘汰赛ObservableArray? (长度为0)

问题描述 投票:4回答:2

我是新来knockout.js(这也是我的第一个计算器后),现在我面临着以下问题。

我无法从网页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);
        });
    });
};
javascript jquery knockout.js asp.net-web-api knockout-3.0
2个回答
7
投票

这条线是有可能是罪魁祸首:

var length = viewModel.InitialData.length;

请记住,InitialData是一个函数。功能有length(这是他们的“元数”,他们有正式的参数的个数),但可观察到的阵列的length可观测的功能是不是数组的length ..

你可能希望它里面的数组的长度:

var length = viewModel.InitialData().length;
// -------------------------------^^

您的各种呼叫push上观察到的阵列工作,即使length不会因为Knockout provides push (and several other things)可观测阵列功能,James points out


同样,这条线:

var newAnnouncement = createAnnouncement(InitialData[i]);

可能想使用阵列以及为(并缺少在viewModel.前面InitialData)。

让整机部分可能要进行重构了一下:

viewModel.InitialData().forEach(function(entry) {
    var newAnnouncement = createAnnouncement(entry);
    viewModel.Announcements.push(newAnnouncement);
});

或不forEach(但实际上,它几乎是2016年,而它的shimmable过时的浏览器);

var data = viewModel.InitialData();
for (var i = 0; i < data.length; ++i) {
    var newAnnouncement = createAnnouncement(data[i]);
    viewModel.Announcements.push(newAnnouncement);
}

附注:您的代码(至少是在问题)也堕入通过不声明你在The Horror of Implicit Globals循环使用ifor。我添加了一个var以上,但这是另外一个原因,通过阵列使用forEach循环。


0
投票

您还可以使用的EcmaScript 6风格的枚举,如下所示:

viewModel.InitialData().forEach(item => {
    let newAnnouncement = createAnnouncement(item);
    viewModel.Announcements.push(newAnnouncement);
});
© www.soinside.com 2019 - 2024. All rights reserved.