Javascript & KnockoutJS 代码重构:如何在函数外部访问Override与Justification属性
解决Knockout.js中从外部访问Override和Justification属性的问题
首先咱们理清你当前代码的核心问题:你的self.CasOverridesViewModel是一个Knockout observable(本质是函数),它内部存储的应该是一个可枚举的集合/数组,而非单个对象。你之前尝试直接调用self.CasOverridesViewModel.Override()报错,就是因为没先获取observable内部的集合,而且集合本身并没有Override属性——Override是集合里每一个子项的专属属性。
另外,你之前用全局变量的思路行不通,是因为extendViewModel遍历过程中的item是局部变量,全局变量只能保存最后一个遍历到的项,还无法响应集合的动态变化。
下面给你两种可行的解决方案:
方案一:将处理后的Override项暴露为ObservableArray
这个方案会把所有添加了isOverrideFilledIn等计算属性的项,存到一个全局可访问的observableArray里,方便你在函数外部随时获取:
self.CasOverridesViewModel = ko.observable(self.CasOverridesViewModel); // 新增一个observableArray,用来存储处理后的所有Override项 self.processedCasOverrides = ko.observableArray([]); var hasOverrides = typeof self.CasOverridesViewModel === typeof(Function); if (hasOverrides) { self.setupOverrides = function() { var extendViewModel = function(obj, extend) { for (var property in obj) { if (obj.hasOwnProperty(property)) { extend(obj[property]); } } }; var rawOverrides = self.CasOverridesViewModel(); extendViewModel(rawOverrides, function(item) { // 简化计算属性逻辑 item.isOverrideFilledIn = ko.computed(function() { return !!item.Override(); }); item.hasAtleastNineWords = ko.computed(function() { var justification = item.Justification(); if (!justification) return false; return justification.trim().split(/\s+/).length > 9; }); item.isJustificationMissing = ko.computed(function() { return !!item.Override() && !item.hasAtleastNineWords(); }); item.isValid = ko.computed(function() { return !item.isJustificationMissing(); }); // 将处理后的项添加到全局可访问的observableArray中 self.processedCasOverrides.push(item); }); }(); }
外部访问方式
之后你就可以在任意地方通过self.processedCasOverrides获取项的属性:
- 获取第一个项的Override值:
if (self.processedCasOverrides().length > 0) { var firstOverrideValue = self.processedCasOverrides()[0].Override(); console.log(firstOverrideValue); } - 遍历所有项获取属性:
self.processedCasOverrides().forEach(function(overrideItem) { console.log("Override值:", overrideItem.Override()); console.log("说明文本:", overrideItem.Justification()); });
方案二:添加全局方法来获取指定项的属性
如果你不想暴露整个集合,也可以给self添加专门的方法,用来获取指定位置或条件的Override/Justification属性:
// 在setupOverrides执行后添加这些方法 self.getOverrideByIndex = function(index) { var overrides = self.CasOverridesViewModel(); if (overrides && overrides[index]) { return overrides[index].Override(); } return null; }; self.getJustificationByIndex = function(index) { var overrides = self.CasOverridesViewModel(); if (overrides && overrides[index]) { return overrides[index].Justification(); } return null; };
外部调用方式
// 获取第0个项的Override var overrideVal = self.getOverrideByIndex(0); // 获取第0个项的Justification var justificationVal = self.getJustificationByIndex(0);
额外注意事项
如果你的CasOverridesViewModel是动态更新的(比如后续会从服务器拉取新数据),你需要监听它的变化,重新处理新集合并更新processedCasOverrides:
self.CasOverridesViewModel.subscribe(function(newOverrides) { self.processedCasOverrides.removeAll(); // 重新执行处理逻辑 extendViewModel(newOverrides, function(item) { // 重新添加计算属性... self.processedCasOverrides.push(item); }); });
内容的提问来源于stack exchange,提问作者TheRealBeginner
相关产品推荐
相关产品推荐

