更新knockout js中的数组项

时间:2014-09-18 08:56:44

标签: javascript jquery arrays knockout.js

我有一组"用户"在KnockoutJS可观察数组中。我可以将用户添加到数组中并正确地更新视图,但是用户的编辑目前让我感到疯狂,可能是因为我对基本概念的理解略有不足。

查看模型

var viewModel = {
    users: ko.observableArray(),
    user: ko.observable(),
    showEditForm: function (model) {
        if (!$('#users-form').is(':visible')) {
            $('#mask').show();
        }
        showUsersLoading();
        loadUserIntoEditForm(model.Id);
    },
    getUser: function (userId) {
        for(var i = 0; i < this.users().length; ++i)
        {
            if (this.users()[i].Id === userId)
            {
                this.user(this.users()[i]);
                break;
            }
        }
    }
};

用户视图模型(此时主要用于添加功能)

   var userViewModel = function (id, username, statusDescription, email) {
        var self = this;
        self.Id = ko.observable(id),
        self.Name = ko.observable(username),
        self.StatusDescription = ko.observable(statusDescription),
        self.Email = ko.observable(email)
    };

更新/编辑在MVC局部视图中执行,该视图触发ajax请求以更新用户服务器端,然后在成功响应时运行以下代码以更新用户

viewModel.getUser(result.Id);
viewModel.user().StatusDescription('locked');
viewModel.user().Name('testingUpdate');

这给了我一个Uncaught TypeError: string is not a function错误

这是我理解失败的地方。我得知我从用户数组中抓取的用户没有可观察的属性,这就是我无法使用Knockout函数方法更新的原因,我已通过拉动确认了这一点在浏览器控制台窗口中输出users数组的详细信息。

我也知道,从概念上讲,我想将用户可观察对象强制转换为userViewModel对象,以便属性变为可观察对象,我可以更新它们;或者我希望用户可观察数组知道它包含的对象应该是userViewModel类型,因此对象属性是可观察的。

我遇到的问题是虽然我理解这个概念,但我无法弄清楚实际使其运作的代码。

2 个答案:

答案 0 :(得分:1)

问题是this关键字。在您的示例中,它并不是指您期望的内容。

尝试使用RMP(显示模块模式)来简化编写代码的方式。它看起来像这样:

var viewModel = (function() {
    var users = ko.observableArray();
    var user = ko.observable();

    // This one changes: you can use the vars directly

    var getUser = function (userId) {
        for(var i = 0; i < users().length; ++i)
        {
            if (users()[i].Id === userId)
            {
                user(this.users());
                break;
            }
        }
    }

    // Reveal the data

    return {
        users: users,
        user: user,
        getUser : getUser
    };

})();  // self-executing anonymous function 

匿名函数会在你的变量周围放置一个闭包。您可以在该闭包内安全地使用变量,并且它们不在其外部。此外,你可以拥有&#34;私人变种&#34;只是不要透露它们。

附加说明:我建议您使用lodashunderscore来简化数组操作:您要避免编写循环来查找数组中的元素。例如,使用lodash find

答案 1 :(得分:0)

一如既往,简单的答案是,我是个白痴。

我缺少的关键部分是忘记我没有处理强类型对象,并假设它们只是以我期望的方式工作。

我的ajax调用成功回调以填充viewModel对象中的users()数组曾经是

success: function (data) {
    viewModel.users(data)
    setupDatatable();
}

回顾一下,问题很明显。我将通用对象插入到数组中,而不是userViewModel对象。

所以,当我把它改为:

success: function (data) {
    for (var i = 0; i < data.length; ++i) {
        viewModel.users.push(new userViewModel(data[i].Id, data[i].Name, data[i].StatusDescription, data[i].Email));
    }
    setupDatatable();
}

突然间它开始工作了。

希望我的愚蠢和痛苦的日子能帮助别人:)