Knockout.js中ko.observableArray()不符合预期的问题求助
问题分析与解决方案
嘿,我来帮你捋清楚这个问题!核心问题其实出在对象字面量初始化时this的指向上,咱们一步步拆解:
为什么第一种写法不工作?
当你在对象字面量里写:
myItems: [ {value: 0, text: 'a'}, {value: 1, text: 'b'}, {value: 2, text: 'c'} ], allItems: ko.observableArray(this.myItems), console.log(this.allItems())
这里的this并不是你正在创建的这个对象!在对象字面量的属性定义阶段,this指向的是当前的执行上下文(比如全局环境的window,或者包裹这个对象的函数上下文),而不是正在初始化的对象本身。所以this.myItems其实根本没拿到你刚刚定义的myItems数组,大概率是undefined,导致allItems这个observableArray初始化时是空的或者错误的。
为什么直接硬编码就正常?
而第二种写法:
allItems: ko.observableArray([ {value: 0, text: 'a'}, {value: 1, text: 'b'}, {value: 2, text: 'c'} ]), console.log(this.allItems())
这里不需要依赖this来获取数组,直接把字面量数组传给ko.observableArray,自然能正确初始化,所以打印也正常。
为什么打印结果看起来一样?
你说打印两者结果看起来没差异,大概率是你打印的时机不对!比如当你在对象创建完成之后再去打印this.allItems(),这时候this已经指向了正确的对象,allItems可能已经被后续代码修正,或者你打印的是已经正确赋值后的状态,但初始化阶段的问题已经发生了。
解决方法
给你两种常用的正确写法:
方法1:使用构造函数(推荐,Knockout常用方式)
用构造函数来定义ViewModel,这样this会指向实例对象,就能正确访问myItems:
function MyViewModel() { // 先定义数组 this.myItems = [ {value: 0, text: 'a'}, {value: 1, text: 'b'}, {value: 2, text: 'c'} ]; // 再用this.myItems初始化observableArray this.allItems = ko.observableArray(this.myItems); console.log(this.allItems()); // 现在能正常输出数组了 } // 创建实例 const vm = new MyViewModel();
方法2:分开初始化对象属性
如果一定要用对象字面量,可以先定义基础属性,再单独初始化observableArray:
const viewModel = { myItems: [ {value: 0, text: 'a'}, {value: 1, text: 'b'}, {value: 2, text: 'c'} ] }; // 此时viewModel已经创建,直接用viewModel.myItems初始化 viewModel.allItems = ko.observableArray(viewModel.myItems); console.log(viewModel.allItems()); // 正常工作
或者用ES6的getter函数(确保每次访问allItems时都能拿到正确的数组):
const viewModel = { myItems: [ {value: 0, text: 'a'}, {value: 1, text: 'b'}, {value: 2, text: 'c'} ], get allItems() { return ko.observableArray(this.myItems); } }; console.log(viewModel.allItems()); // 正常输出
内容的提问来源于stack exchange,提问作者Juliano Vargas
相关产品推荐
相关产品推荐

