【问题标题】:Update an array item in knockout js更新淘汰赛js中的数组项
【发布时间】:2014-11-12 12:54:00
【问题描述】:

我在 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 错误

这是我的理解失败的地方。我知道我从 users 数组中获取的用户没有可观察的属性,这就是为什么我无法使用 Knockout 函数方法进行更新的原因,我通过提取 users 数组中的详细信息确认了这一点浏览器控制台窗口。

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

我遇到的问题是,虽然我理解了这个概念,但我无法弄清楚使其真正起作用的代码。

【问题讨论】:

    标签: javascript jquery arrays knockout.js


    【解决方案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 
    

    匿名函数在你的变量周围放置一个闭包。您可以在该闭包内安全地使用这些变量,并且它们在该闭包之外不可用。此外,您可以通过不透露它们来拥有“私有变量”。

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

    【讨论】:

    • 感谢您的回答,但我仍然遇到同样的错误。我必须对您的代码进行的一项小改动是 user(this.users());只是用完整的用户列表填充用户对象,所以我将其更改为 user(this.users()[i]);
    【解决方案2】:

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

    我遗漏的关键部分是忘记了我不是在处理强类型对象,并假设它们会按我期望的方式工作。

    我的 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();
    }
    

    它突然开始工作了。

    希望我的愚蠢和几天的头痛能帮助别人:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-11-03
      • 2014-10-30
      • 1970-01-01
      • 2020-06-23
      • 2013-02-24
      • 2017-08-08
      • 1970-01-01
      相关资源
      最近更新 更多