在Knockout中,我有一组writeLines()
个实体,它们可能是不同的类型(即设置实体的'子类')。这些类型是动态的,用户可以在UI中更改它们。根据Setting实体的类型,它需要不同的对象属性,并使其他属性变得多余。
我目前正在做的事情(我想要改变)是定义一个设置构造函数,它具有所有设置类型的所有必需属性;使构造函数非常庞大,并包含许多不必要的属性。保存应用数据后,我会忽略'不应该根据其类型设置实例的属性。
我已经在this fiddle中尝试了一下,使用Setting
属性上的订阅来添加/删除类型更改的属性。我想知道在KnockoutJS中是否有可能在运行时期间可靠地更改对象的属性(即订阅是否会在模板更新之前始终触发?)并且这样做对绩效有任何[正面]影响?。或者这种方法是完全错误的,我应该用子类实例替换整个对象(如果是这样,赢得订阅会丢失)?
编辑:从属属性是实际数据(因此它们应保存到模型中,不仅在视图中可用)。我已尝试过组件方法,但如何在以后检索其属性? http://jsfiddle.net/kevinvanlierde/zmx3u4an/1/
答案 0 :(得分:1)
使用在设置编辑器中绑定但由每个子类实例拥有的组件。
<div data-bind="foreach: settings">
<select data-bind="options: $root.types, value: type"></select>
<input type="text" data-bind="textInput: value"/>
<div data-bind="component: { name: componentName, params: componentParams }"></div>
</div>
颜色设置的示例组件名称/参数。对于不同的设置子类,这些属性会有所不同。
this.componentName = 'color-viewer';
this.componentParams = {
colorText: this.value,
};
使用这种方法,更改当前设置&#34;键入&#34;会要求您将一个设置子类实例替换为另一个。这可能是一个简单的案件中的麻烦,但是保持你的模型只有一个单一的责任有其优势。
答案 1 :(得分:1)
为了解决保存属性的问题,我重新编写了组件代码。一些成员(主要是计算机)仅用于视图,不应保存,因此我将可保存的内容放在“数据”成员中:
function Setting(params) {
var self = this;
// What getData fetches
self.data = {
type: ko.observable(params.type),
value: ko.observable(params.value || '')
};
self.data.type.subscribe(function (value) {
// Give the conversion a little time
setTimeout(function () {
console.log("GetData:", self.getData());
}, 30);
});
}
每个专用类型都会将其特殊成员添加到基础对象,并添加一个方法toSetting
,以将其还原为基础对象类型。基类型在其原型中具有无效版本toSetting
,因此在类型转换器中首先调用toSetting
始终是安全的。
我在Title类型中添加了headingSize
参数,并确定了文本显示的标题大小。
function toTitle(setting) {
var self = setting;
var data = setting.data;
var value = data.value();
self.toSetting();
data.headingSize = ko.observable(4);
self.capitalized = ko.computed(function () {
return value ? value.slice(0, 1).toUpperCase() + value.slice(1) : '';
});
self.headerText = ko.computed(function () {
return '<h' + data.headingSize() + '>' + self.capitalized() + '</h' + data.headingSize() + '>';
});
self.toSetting = function () {
delete self.data.headingSize;
delete self.capitalized;
delete self.toSetting;
};
return self;
}
我注册了这样:
ko.components.register('title', {
viewModel: toTitle,
template: '<select data-bind="options:$root.sizes, value: data.headingSize"></select><div data-bind="html:headerText"></div>'
});
我添加了一个“保存”设置的按钮,显示将保存在页面底部的内容。