ObservableArray 中的第一个数组项

Posted

技术标签:

【中文标题】ObservableArray 中的第一个数组项【英文标题】:First Array Item in ObservableArray 【发布时间】:2017-12-31 02:13:46 【问题描述】:

我正在尝试使用 knockoutJS 填充级联 select2 下拉菜单。 代码在使用function staticbuildData() 中的静态数据时似乎运行良好,但在使用函数function buildData() 时会引发错误。

第一个下拉菜单正确填充数据,但是,在第一个下拉菜单中选择项目时,会引发以下错误:

未捕获的类型错误:无法读取 null 的属性“childOptions”

原来下面这行找不到子选项并返回null:

 var make = ko.utils.arrayFirst(viewModel.togaMakers,function(item)

我唯一能想到的是 staticbuildData() 返回一个数组,而 buildData() 返回一个 observableArray,因此找不到正确的子选项。

我是在正确的轨道上还是有人知道为什么会发生这种情况?

淘汰赛

var viewModel = 
    togaMakers: buildData(),
    // togaMakers: staticbuildData(),
    selectedInstitution : ko.observable(),
    selectedLevel : ko.observable(),
    selectedFaculty : ko.observable()
;

viewModel.togaLevels = ko.computed(function()
    if(viewModel.selectedInstitution())
        console.log(buildData());
        var make = ko.utils.arrayFirst(viewModel.togaMakers,function(item)
            console.log(item.text,viewModel.selectedInstitution());
                return item.text===viewModel.selectedInstitution();          
        );
        return make.childOptions;
     
);

viewModel.togaFaculties = ko.computed(function()
    if(viewModel.selectedLevel())
        var type = ko.utils.arrayFirst(viewModel.togaLevels(),function(item)
            console.log(item.text,viewModel.selectedLevel());
                return item.text===viewModel.selectedLevel();
          console.log("Answer:" + item);
        );
        return type.childOptions;
     
);
ko.cleanNode(viewModel);
ko.applyBindings(viewModel);

buildData()

function buildData() 
  var dataContainer = ko.observableArray([]);

  getData().then(function(newData) 
    parsed = JSON.parse(newData);
    processed = processData(parsed);
    dataContainer(processed);
  );

  return dataContainer;
;

静态构建数据

function staticbuildData()
    var uomBachelor = new cascadingOption(
        text: 'Bachelor Degree',
        childOptions : [
            new cascadingOption(
                text: 'Faculty of Enviroment'
            ),
            new cascadingOption(
                text: 'Faculty of Education'
            )
        ]
    );

    var uomMaster = new cascadingOption(
        text: 'Master Degree',
        childOptions : [
            new cascadingOption(
                text: 'Faculty of Law'
            ),
            new cascadingOption(
                text: 'Faculty of Dental & Surgery'
            )
        ]
    );

    var uom = new cascadingOption(
        text: 'University 1',
        childOptions : [uomBachelor, uomMaster]
    );

    var mdx = new cascadingOption(
        text: 'University 2',
        childOptions : [
            new cascadingOption(
                text:'Bachelor Degree',
                childOptions : [
                    text: 'Q5',
                    text: 'Q7'
                ]
            ),
            new cascadingOption(
                text:'Master Degree',
                childOptions : [
                    text: 'A3',
                    text: 'A4',
                    text: 'A6'
                ]
            )
        ]
    );
    return [uom, mdx];

【问题讨论】:

我可以看看你的 html,或者最好是 jsfiddle。 【参考方案1】:

您正在处理异步数据。 buildData 函数将首先返回一个空的可观察数组,然后然后添加数据。

然而,togaLevel 的计算将在以下时间进行评估:

第一次实例化 selectedLevel 变化 togaMakers 变化

这意味着当selectedLevel 为真且togaMakers 仍为空时,您将收到错误消息。 computed 的值将被评估,它会尝试在空数组中找到第一个(返回null),然后尝试获取null.childOptions

快速解决方法是将return 语句更改为:

return type ? type.childOptions : null;

这通过返回null 使计算句柄为空数组。

【讨论】:

感谢 @user3297291 澄清并帮助我理解问题。我将研究“异步依赖的 Observables”。

以上是关于ObservableArray 中的第一个数组项的主要内容,如果未能解决你的问题,请参考以下文章

仅从 ko.observableArray 发送更新的对象

observableArray未通过完整数组传递更新

力扣算法笔记—1_删除排序数组中的重复项(数组)

遍历数组,并将子 JSON 转换为 observablearray?

Knockout-Kendo dropdownlist Ajax observableArray 获取选中项名称

knockoutJS-04之observableArray监控数组