无法在句柄if语句中填充字段

时间:2015-01-11 06:55:59

标签: javascript meteor modal-dialog

我有一个模式框,其中包含一些字段,根据其他字段中的某些值,它们可能会出现也可能不出现。

因此字段看起来像

<div class="row">
  <select class="form-control" id="ddlNewInputType" placeholder="Enter your input type">
    <option value="input">Input</option>
    <option value="formula">Formula</option>
  </select>
</div>


{{#if isFormula }}
  <div class="row">
    <input type="text" id="txtNewInputFormula" placeholder="Enter formula">
  </div>
{{/if}}

有一个帮助程序可以确定是否显示了txtNewInputFormula文本框

isFormula: ->
  return Template.instance().isFormula.get();

isFormula是一个ReactiveVar,在下拉列表更改时会填充

'change #ddlNewInputType': (e,t) ->
  isFormula = $(e.currentTarget).val() == 'formula'
  t.isFormula.set(isFormula);

实际上,规则是输入类型=输入,不显示公式字段,如果输入类型=公式,则显示公式字段。

当我的模态框加载时,它是新对象或现有对象。如果它是现有对象,我使用数据库中的值预先填充模态框,如此

'click #btnEditInput': ->
    $('#addInputModal').modal()
    $('#txtNewInputName').val(this.name)
    $('#txtNewInputFormula').val(this.formula)
    $('#ddlNewInputType').val(this.inputType)
    $('#ddlNewInputType').change()

问题是每个字段除了正在填充txtNewInputFormula之外。我怀疑txtNewInputFormula没有填充,因为它在句柄if if语句中并且尚未被评估,因此HTML元素不存在。

我该如何解决这个问题?如何在IF语句中填充HTML元素?

4 个答案:

答案 0 :(得分:4)

您的诊断可能是正确的,您是否尝试使用把手语法以适当的数据反复填充输入文本值?

这样的事情:

{{#if isFormula }}
  <div class="row">
    <input type="text" id="txtNewInputFormula" placeholder="Enter formula" value="{{formula}}">
  </div>
{{/if}}

无论何时最终创建DOM元素,都将输入值设置为反应性助手。

一般来说,当你发现自己操纵jQuery来修改DOM并绕过Blaze时,你可能会遇到麻烦。

答案 1 :(得分:1)

我同意@saimeunt,你不应该像这样用jQuery操纵DOM。您应该考虑使用包装器将模板模板添加到DOM并提供数据。

但是,如果您想让代码正常工作,您可以。

基本上,您希望将更新延迟到#txtNewInputFormula,直到下一次刷新。

'click #btnEditInput': ->
    formula = this.formula
    Tracker.afterFlush ->
      $('#txtNewInputFormula').val(formula)
      return
    $('#txtNewInputName').val(name)
    $('#ddlNewInputType').val(this.inputType).change()
    $('#addInputModal').modal()
    return

答案 2 :(得分:0)

另一种解决方案是使用autoform包。

在架构中,您可以定义字段取决于另一个字段。然后当你打电话 {{#autoform collection=...}}{{afInputField...}}...{{/autoform}},它会显示或隐藏相应的字段。

可以找到一个示例here,其中包含2个字段A和B:B将显示是否选择了A:

架构:

FieldValueIs = new Mongo.Collection("FieldValueIs");
FieldValueIs.attachSchema(new SimpleSchema({
  a: {
    type: String,
    allowedValues: ["foo", "bar"]
  },
  b: {
    type: String
  }
}));

HTML表单:

{{#autoForm collection="FieldValueIs" type="insert" id="FieldValueIsForm"}}
  {{> afQuickField name="a" options="allowed" noselect=true}}
  {{#if afFieldValueIs name="a" value="foo"}}
    {{> afQuickField name="b"}}
  {{/if}}
{{/autoForm}}

答案 3 :(得分:0)

您是否考虑过将if语句的内容放入其自己的模板中并使用模板的rendered函数填充它?我假设这是流星,因为你的标签。

这当然只是部分代码,但是类似于:

HTML:

<template name="someTemplate">
  //....
  <div class="row">
    <select class="form-control" id="ddlNewInputType" placeholder="Enter your input type">
      <option value="input">Input</option>
      <option value="formula">Formula</option>
    </select>
  </div>
  {{#if isFormula }}
    {{>formulaInput}}
  {{/if}}
  //....
</template>


<template name="formulaInput">
  <div class="row">
    <input type="text" id="txtNewInputFormula" placeholder="Enter formula">
  </div>
</template>

JS:

Template.formulaInput.rendered = function(){
    //do the populating
}

渲染函数时会调用渲染函数,在这种情况下,当isFormula辅助函数返回true时。流星manual有关于Blaze / Template如何工作的一些很好的信息。