首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AlpacaJS:动态表行中可观察到的引用字段

AlpacaJS:动态表行中可观察到的引用字段
EN

Stack Overflow用户
提问于 2020-05-06 20:13:08
回答 1查看 302关注 0票数 0

我有一个表元素,人们可以在其中添加行来添加数据。其中两个字段是相互排斥的:如果您在一个字段中输入一个值,则另一个字段应该禁用,反之亦然。我的理解是,我需要在postRender回调中使用可观察的方法来完成这个任务,但是我似乎找不到正确的路径或in字符串。从逻辑上讲,它的工作方式没有多大意义。桌子一开始是空的。

那么,对“添加行”按钮是否有回调,或者我需要在其中添加这个逻辑?如有任何指导,将不胜感激。

模式:

代码语言:javascript
复制
    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"
                        }
                    }
                }
            }
        }
    };

下面的代码不起作用(同样,考虑到这一点并不令人惊讶,但我不知道还可以尝试什么):

代码语言:javascript
复制
    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修复了持久性禁用问题:

代码语言:javascript
复制
    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对象的相关片段:

代码语言:javascript
复制
            "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)),但它现在已经足够功能了。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-05-07 15:36:45

您的模式是正确的,而且您所想到的也是正确的--使用postRender总是有帮助的,但在这种情况下,并不是太多,因为您有类似于嵌套的字段/对象(数组>项>项目1>小时)--这就是为什么您的代码不能工作,因为您不能为所有已创建项的所有小时分配更改函数!另外,您正在对一个数字使用getValue().length (请参见您的模式配置),这将永远不会起作用,您应该在number字段上使用toString或is isNaN

因此,要实现您想要的目标,您应该创建一个options config并将其分配给羊驼选项字段。在这个配置中,您应该在百分比和小时字段上使用change event,并为每个字段在postRender上放置相同的代码。

下面是一个例子:

代码语言:javascript
复制
"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中,您已经有了一个全局控制变量,可以用来获取字段控件对象,但是这里我们在子控件上,因此可以使用父控件执行它,如下所示:

代码语言:javascript
复制
var percent = this.parent.childrenByPropertyId["percent"];

在为您的工时或百分比字段设置了任何选项之后,您应该调用refresh()函数来告诉羊驼您更新了一些配置,并使用更新的配置为我们重新呈现了该字段。

代码语言:javascript
复制
percent.refresh();

下面是这个解决方案的工作小提琴

为了回答你关于“添加行”按钮的问题,是的,这里有一个回调函数,但是我认为它不会对你有帮助,不过,我试过了,在数组类型字段中,你有两个不同的添加按钮,所以对我来说这不是一个好的解决方案,因为你应该为两个按钮实现代码!当您有0项时,第一项(工具栏按钮);第二项,当您开始添加项目时(动作按钮)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61644505

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档