我有一个表格元素,人们可以在其中添加行以添加数据。其中两个字段是互斥的:如果您在一个字段中输入一个值,则应禁用另一个字段,反之亦然。我的理解是,我需要使用可观察对象在postRender
回调中执行此操作,但是我似乎找不到正确的路径或ID字符串。从逻辑上讲,它如何工作没有多大意义。该表开始为空。
因此,是否存在“添加行”按钮的回调或需要添加此逻辑的内容?任何指导将不胜感激。
架构:
var schema = {
"type": "object",
"properties": {
"cbnum": {
"type": "string",
"required": true,
"minLength": 5,
"maxLength": 5
},
"projects": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"title": "Project name (required)",
"required": true
},
"tags": {
"type": "string",
"title": "Tags"
},
"hours": {
"type": "number",
"title": "Hours"
},
"percent": {
"type": "number",
"title": "Percent"
}
}
}
}
}
};
以下代码不起作用(再次考虑时,这并不奇怪,但我不知道该尝试什么):
var postRenderCallback = function(control) {
var hours = control.childrenByPropertyId["projects"].childrenByPropertyId["hours"];
var percent = control.childrenByPropertyId["projects"].childrenByPropertyId["percent"];
hours.on("change", function() {
if (this.getValue().length > 0) {
percent.setValue("");
percent.options.disabled = true;
} else {
percent.options.disabled = false;
}
});
percent.on("change", function() {
if (this.getValue().length > 0) {
hours.setValue("");
hours.options.disabled = true;
} else {
hours.options.disabled = false;
}
});
};
更新资料
以下
postRenderCallback
修复了持久禁用问题: var postRenderCallback = function(control) {
var table = control.childrenByPropertyId["projects"];
table.on("add", function() {
var lastrow = this.children[this.children.length-1];
var hours = lastrow.childrenByPropertyId["hours"];
var percent = lastrow.childrenByPropertyId["percent"];
hours.options.disabled = false;
percent.options.disabled = false;
hours.refresh();
percent.refresh();
});
};
但是后来我遇到了另外两个问题,这使整个解决方案成为问题(最大的问题是我无法找到一种方法来将数字字段设置为空白或
undefined
;它一直显示为NaN
)。因此,我采用了以下解决方案,就足够了。以下是options
对象的相关代码段: "projects": {
"type": "table",
"actionbarStyle": "bottom",
"items": {
"fields": {
"tags": {
"type": "tag"
},
"hours": {
"allowOptionalEmpty": true,
"validator": function (callback) {
var that = this.parent.childrenByPropertyId["percent"];
var thisValue = this.getValue();
var thatValue = that.getValue();
if ( (typeof thisValue !== "undefined" && !isNaN(thisValue)) && (typeof thatValue !== "undefined" && !isNaN(thatValue)) ) {
callback({
"status": false,
"message": "You can only enter a number into one of the fields, if any. You may not have numbers in both."
});
} else {
callback({
"status": true
});
}
}
},
"percent": {
"allowOptionalEmpty": true,
"validator": function (callback) {
var that = this.parent.childrenByPropertyId["hours"];
var thisValue = this.getValue();
var thatValue = that.getValue();
if ( (typeof thisValue !== "undefined" && !isNaN(thisValue)) && (typeof thatValue !== "undefined" && !isNaN(thatValue)) ) {
callback({
"status": false,
"message": "You can only enter a number into one of the fields, if any. You may not have numbers in both."
});
} else {
callback({
"status": true
});
}
}
}
}
}
}
仍然不是一个完美的UX解决方案(我似乎无法使一个字段的验证器执行另一字段的验证器;我尝试了
this.parent.validate(true)
),但是到目前为止它的功能已经足够了。 最佳答案
您的模式是正确的,并且使用postRender
所考虑的内容也是正确的,但总是有帮助,但在这种情况下,它并不太有用,因为您喜欢嵌套的字段/对象(数组>项目>项目1>小时),这就是为什么代码无法使用,因为您无法将更改功能分配给所有已创建项目的所有时间!加上您在数字上使用getValue().length
(请参阅架构配置),这将永远无法工作,您应该使用toString
或在isNaN
字段上使用number
。
因此,要实现所需的功能,应创建一个options config
并将其分配给羊驼毛选项字段。并且在此配置中,您应在百分比和小时数字段上使用change event
,并将与每个字段相同的代码放在postRender上。
这是一个例子:
"hours": {
"events": {
"change": function() {
var percent = this.parent.childrenByPropertyId["percent"];
var hoursValue = this.getValue();
if (typeof hoursValue != 'undefined' && !isNaN(hoursValue)) {
percent.options.disabled = true;
} else {
percent.options.disabled = false;
}
percent.refresh();
}
}
}
在
postRender
中,您已经有一个全局控件变量,可以用来获取字段控件对象,但是这里我们在子控件上,因此可以使用父控件来做到这一点,如下所示:var percent = this.parent.childrenByPropertyId["percent"];
在为小时或百分比字段设置了任何选项后,应调用
refresh()
函数,以通知羊驼您更新了一些配置,并使用更新后的配置为我们重新渲染该字段。percent.refresh();
这是此解决方案的有效fiddle。
并回答您有关“添加行”按钮的问题,是的,有一个回调,但是我认为它对数组类型字段没有帮助,但是我尝试使用数组类型字段有2个不同的添加按钮,因此对我来说,这不是一个好的解决方案,因为您应该为两个按钮实现代码!当您有0个项目时,第一个按钮(工具栏按钮);当您开始添加项目时,第二个按钮(操作按钮)。
关于javascript - AlpacaJS:动态表行中的可观察引用字段,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/61644505/