Javascript 需要更好的方法来处理复杂的条件形式逻辑&;使用Ractive.js进行验证

Javascript 需要更好的方法来处理复杂的条件形式逻辑&;使用Ractive.js进行验证,javascript,forms,validation,ractivejs,Javascript,Forms,Validation,Ractivejs,我目前正在用大量的条件逻辑构建一个相当复杂的表单。我的意思是,当用户选中一个选项时,可能会显示或隐藏一个或多个其他选项-您可能已经见过很多次了 使用Ractive的mustache模板和许多{{{#if}}语句,我创建了表单,但是验证和提交的逻辑需要改进。只有当所有“可见”字段都有效时,我才需要启用“提交”按钮,因此我得出结论,每个字段都需要一个isInUse属性以及isValid,请参见下面的示例: data: { foo: { isValid: false,

我目前正在用大量的条件逻辑构建一个相当复杂的表单。我的意思是,当用户选中一个选项时,可能会显示或隐藏一个或多个其他选项-您可能已经见过很多次了

使用Ractive的mustache模板和许多
{{{#if}}
语句,我创建了表单,但是验证和提交的逻辑需要改进。只有当所有“可见”字段都有效时,我才需要启用“提交”按钮,因此我得出结论,每个字段都需要一个
isInUse
属性以及
isValid
,请参见下面的示例:

data: {
    foo: {
        isValid: false,
        isInUse: false,
        value: ''
    }
}
这样做的原因是一个字段可以被设置为可见,但是一个选项可以隐藏它&它可能仍然有一个用户不需要提交的值

我还确定,更改
isInUse
属性的唯一可靠方法是在我的数据中创建一个可以从我的模板访问的函数,如下所示:

data: {
    foo: {
        isValid: false,
        isInUse: false,
        value: ''
    },

    isInUse: function (keypath, bool) {
        ractive.set(keypath, bool);
    }
}
这在我的模板中使用,如下所示:

{{#if choice.email}}
      {{ isInUse('validate.email.isInUse', true) }}
      {{ isInUse('validate.phone.isInUse', false) }}

      <label for="email">Email</label>
      <input type="text" id="email" value="{{validate.email.value}}">
{{/if}}
{{{#if choice.email}
{{isInUse('validate.email.isInUse',true)}
{{isInUse('validate.phone.isInUse',false)}
电子邮件
{{/if}
这意味着我可以更改模板端的值。。这意味着我可以检查每个字段是否正在使用且有效。。这就是我质疑实施的地方,这是个好主意吗


我已经在jsbin上创建了一个简单的表单版本(它完全可以用于验证和提交),请参见:但是我的表单要复杂得多,所以我想找到一种优雅的方式来处理所有这些

从模板中调用
isInUse
是一个非常有创意的解决方案,但不幸的是很可能会失败

您应该将模板中的表达式视为只读的-您可以在表达式中调用函数,但只能获取其值,而不能因为设置另一个值等副作用(一个可能的异常是记录输出以进行调试)。原因是,您无法直接控制调用函数的时间(代表您的操作),因此您可能会得到意外的结果。在上面的示例中,将
choice.email
true
更改为
false
不会产生预期效果

您可能需要计算属性。这些属性可以像常规属性一样在模板内读取,只是它们的值取决于其他数据(或其他计算属性):

ractive=新的ractive({
el:‘身体’,
模板:'tweeth{{foo}}是{{doubleFoo}}',
数据:{foo:1},
计算:{
doubleFoo:function(){
返回2*this.get('foo');
}
}
});
每当
foo
发生变化时,
doubleFoo
就知道(因为我们在其定义中调用了
this.get('foo')
),它应该重新计算自己。您可以像使用任何其他值一样使用计算值-例如,
ractive.observe('doubleFoo',doSomething)

这对于验证非常有用:

var-ractive=新的ractive({
el:'主要',
模板:`
接触式
电子邮件
电话
名称
名称有效:{{nameIsValid}

{{#如果contactType==“email”} 电子邮件 电子邮件有效:{emailIsValid}

{{/if}}`, 计算:{ nameIsValid:函数(){ return!!this.get('name'); }, emailIsValid:函数(){ var email=this.get('email'); //永远不要实际使用这个正则表达式 返回/^\w+@[a-zA-Z\+?\[a-zA-Z]{2,3}$/.test(电子邮件); } } });


感谢您的回复,我将尝试使用计算值来满足我的需要,并让您知道我的进展情况。此外,感谢创建RaSc活性,它是辉煌的。还认识到,如果HTML表单验证足够满足您的需要,它只会考虑呈现的元素,所以根据定义,任何看不见的东西都不会被验证!Hi@rich harris,计算值有助于验证,但我不确定它们是否解决了哪些字段正在使用(即可见)的问题,除非我遗漏了什么。我的
isInUse()
解决方案解决了问题,但正如您正确指出的,它不是一个可靠的解决方案。有没有其他方法可以做到这一点?@martypdx,谢谢你的建议,我一直在研究这一点,但也希望有一种可靠的方法适用于较旧的浏览器。我会调查的it@Zander字段是否可见取决于表单其余部分的状态-在上面的示例中,电子邮件字段正在使用,因为
contactType==“email”
。因此,与其问“电子邮件字段是否可见”,不如问“联系人类型是否为“电子邮件”?”——这样,您就不会以多种方式表示相同的状态。如果您需要封装该检查,您可以创建一个新的计算属性(
emailIsVisible
或其他任何内容),该属性仅等同于
contactType==“email”