为什么knockoutjs js不't更新视图,如果一些子数组被改变

Why knockoutjs js doesn't update view in case some sub array is changed

本文关键字:如果 改变 数组 新视图 更新 js knockoutjs 为什么      更新时间:2023-09-26

我有next model wirt sub array

<!-- ko foreach: {data: userAdminView.viewRoles, as: 'rrole'} -->
<tr>                                                    
  <td class="userRolesRoleTitle"><b data-bind="text: rrole.role.name"></b><br/><i data-bind="text: rrole.role.description"></i></td>                                
  <td class="userRolesRoleGroups">
    <!-- ko foreach: {data: rrole.role.groups, as: 'group'} -->
    <div class="usersGroupElement" data-bind="html: group.viewName"></div>
    <!-- /ko -->
    <a class="btn emb green" data-bind="click: userAdminView.addNewGroup,visible:(rrole.role.isNewGroupAccessible) , attr: { value: rrole }"><i class="icon16 plus"></i>add</a>
  </td>
</tr>
<!-- /ko -->

它工作得很好,但从业务需要,我需要在 role.role中动态更改数据。组赋。我的代码正在工作,这样做,我看到数组在调试模式下被改变(添加,删除元素),但视图只有在userAdminView时才更新。viewRoles数组得到更改。为什么knockoutjs做不到?我该如何解决这个问题?

function userAdminView(user) {
    var self = this;
    self.viewRoles = ko.observableArray([]);
    self.saveNewGroup = function (data, event) {
        var datar = self.viewRoles();
        $.each(datar, function (index, vrole) {
            if (vrole.role.id == self.dialogRole.role.id) {
                var line = {
                    viewName: "<b>" + self.dialogCustomer.name + "</b>",
                    customer: self.dialogCustomer,
                    department: self.dialogDepartment,
                    isEdit: true
                };
                if (vrole.role.groups == null) {
                    vrole.role.groups = [];
                }
                vrole.role.groups.push(line);
            }
        });
    };
}
数据结构:

{
    role: {
        description: role.description,
        id: role.id,
        name: role.name,
        groups: existingGroups,
        isNewGroupAccessible: self.canGrant(role, data.d)
    }
};

谢谢。

我们可以看看你的惊艳模型吗?子组是observableArray()吗?如果不是,它将不会更新。

编辑:

我通常处理子数组的方式是手动映射顶级observableArray,然后为子数组创建第二个observableArray。Knockout在ko.utils名称空间中有一些方便的实用程序,我们可以使用它们,即Knockout utils。ko。utils函数ko.utils.arrayForEach接受一个数组并返回一个数组,并接受一个函数,该函数将被称为原始数组中的forEach项。这是我们可以做映射的地方。

    var dataFromServer = ko.utils.parseJson(JSONdataFromServer);
    //now that we have a javascript object we can pass that into ko.utils.arrayForEach
    viewModel.viewRoles = ko.utils.arrayForEach(dataFromServer, function(viewRole) {
        var newRole = {
            groups : ko.observableArray(ko.utils.arrayForEach(viewRole.group, function(group) {
                var newGroup = {
                    //map the properties from your JSON group to this object
                };
                return newGroup;
            })),
            //map any other properties from your JSON role to this object
        };
        return newRole;
    });

一旦我们将JSON数据作为javascript对象,我们可以将其传递给ko.utils.arrayForEach。我们向ko.utils.arrayForEach传递javascript数组和一个函数,它将为该数组中的每个项目调用该函数,这些项目是您的角色。第一个函数用子数组创建一个新的Role对象,该子数组也是一个名为groups的observableArray()。

让我知道,如果有任何困惑,我可以试着解释更多。另外,我还没有实际运行这些代码,所以可能会有错误。

角色。

这应该为您工作:

if (typeof vrole.role.groups !== 'function') {
    vrole.role.groups = ko.observableArray(vrole.role.groups);
}