我目前正在构建一个包含大量条件逻辑的相当复杂的表单。我的意思是,当用户检查一个选项时,可能会显示或隐藏一个或多个其他选项 - 您之前可能已经多次看到它..
使用Ractive的胡子模板和许多{{#if }}
语句我创建了表单,但验证和提交的逻辑需要改进。我需要仅在所有“可见”字段有效时启用提交按钮,因此我得出结论,每个字段都需要isInUse
属性以及isValid
,请参阅下文举个例子:
data: {
foo: {
isValid: false,
isInUse: false,
value: ''
}
}
这样做的原因是可以创建一个字段visible
但是一个选项可以隐藏它&它可能仍然具有用户无需提交的值。
我还确定更改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}}
这意味着我可以更改模板端的值..这意味着我可以检查每个字段是否正在使用和有效..现在这是我质疑实现的地方,这是一个好主意吗?
我在jsbin上创建了一个简单版本的表单(完全适用于验证和提交),请参见此处:http://jsbin.com/wasoxa/2/edit?html,js,output但我的表单要复杂得多,所以我'我想找到一种处理所有这些的优雅方式。
答案 0 :(得分:2)
从模板中调用isInUse
是一个非常有创意的解决方案,但不幸的是很可能会破解!
您应该将模板中的表达式视为只读 - 您可以在表达式中调用函数,但只能获取其值,而不是为了设置其他值等副作用(一个可能的例外是记录输出以进行调试)。原因是您无法直接控制函数何时被调用--Ractive代表您处理 - 因此您可以获得意外结果。在上面的示例中,将choice.email
从true
更改为false
将无法达到预期的效果。
您可能需要计算属性。这些可以像常规属性一样在模板内读取,除了它们的值取决于其他数据(或其他计算属性):
ractive = new Ractive({
el: 'body',
template: 'twice {{foo}} is {{doubleFoo}}',
data: { foo: 1 },
computed: {
doubleFoo: function () {
return 2 * this.get( 'foo' );
}
}
});
每当foo
发生变化时,doubleFoo
都知道(因为我们在其定义中调用了this.get('foo')
)它应该重新计算自己。您可以像使用任何其他值一样使用计算值 - 例如ractive.observe('doubleFoo',doSomething)
。
这对验证非常有用:
var ractive = new Ractive({
el: 'main',
template: `
<h2>contact type</h2>
<label>
<input type="radio" name="{{contactType}}" value="email"> email
</label>
<label>
<input type="radio" name="{{contactType}}" value="telephone"> telephone
</label>
<h2>name</h2>
<input type="text" value="{{name}}">
<p>name is valid: {{nameIsValid}}</p>
{{#if contactType === "email"}}
<h2>email</h2>
<input type="text" value="{{email}}">
<p>email is valid: {{emailIsValid}}</p>
{{/if}}`,
computed: {
nameIsValid: function () {
return !!this.get( 'name' );
},
emailIsValid: function () {
var email = this.get( 'email' );
// never actually use this regex
return /^\w+@[a-zA-Z_]+?\.[a-zA-Z]{2,3}$/.test( email );
}
}
});
<script src="http://cdn.ractivejs.org/latest/ractive.js"></script>
<main></main>