1

我是 Ember.js 的新手,有一个关于清理代码的问题。我正在使用 Ember(v1.0.0-rc.1)、Handlebars("1.0.0-rc.3") 和 Bootstrap(v2.3.1)。

以我的以下模板之一:

<form class="form-horizontal">

  <div class="control-group">
    <label class="control-label" for="inputEmail">Name</label>
    <div class="controls">
      {{view Ember.TextField valueBinding="name" id="inputEmail"}}
    </div>
  </div>

  <div class="control-group">
    <label class="control-label" for="inputNumber">ID Number</label>
    <div class="controls">
      {{view Ember.TextField valueBinding="number" id="inputNumber"}}
    </div>
  </div>

  <div class="control-group">
    <label class="control-label" for="inputContactName">Contact Name</label>
    <div class="controls">
      {{view Ember.TextField valueBinding="invoiceContactName" id="inputContactName"}}
    </div>
  </div>

  <div class="control-group">
    <label class="control-label" for="inputContactEmail">Contact Email</label>
    <div class="controls">
      {{view Ember.TextField valueBinding="invoiceContactEmail" id="inputContactEmail"}}
    </div>
  </div>
</form>

现在我有了这个丰富的视图框架,所有的重复都感觉很肮脏!问题是模板的性质......我也需要传入我正在绑定的对象,并更改模板将呈现的值。我的第一次尝试是“嵌套”Handlebars 模板……这很混乱,我什么也没有。我的第二次尝试是创建一个“预处理器”来在 Handlebars 编译模板字符串之前对其进行修改……这看起来更简洁,但根本不起作用……结果是当我们在视图上调用“模板”时是脱离上下文的方式。下面的例子:

App.BootstrapTextField = Ember.View.extend({
  displayLabel: null, 
  valueToBind: null,
  classNames: ['control-group'],

  templateString: '<div class="control-group">' +
                    '<label class="control-label" for="input##valueToBind##">##displayLabel##</label>' +
                    '<div class="controls">' +
                      '{{view Ember.TextField valueBinding="##valueToBind##" id="input##valueToBind##"}}' +
                    '</div>' +
                  '</div>',

  preprocessTemplate: function () {
   var template =  this.templateString.replace(/##valueToBind##/g, this.get('valueToBind'));
   return template.replace(/##displayLabel##/, this.get('displayLabel'));
  },

  template: Ember.Handlebars.compile(this.preprocessTemplate())
})

错误:

Uncaught TypeError: Object [object global] has no method 'preprocessTemplate'

我的问题是:清理它的最佳方法是什么?

4

2 回答 2

1

在我的脑海中,我认为使用带有 layout 属性的 Ember Mixin 可以帮助你实现你想要的。

App.BootstrapMixin = Em.Mixin.extend({
  layout: Em.Handlebars.compile(
              '<div class="control-group">' +
                '<label class="control-label" for="input##valueToBind##">##displayLabel##</label>' +
                '<div class="controls">' +
                  '{{yield}}' +
                '</div>' +
              '</div>')

})

然后你可以像这样定义你的自定义引导视图:

 App.BootstrapTextField = Em.TextField.extend(App.BootstrapMixin, {
    // your custom logic
 })

并将其包含在模板中,如下所示:

<form class="form-horizontal">
   {{view App.BootstrapTextField valueBinding="name" id="inputEmail"}}
   .. 
   ..
</form>

我还没有完全检查以确保这一切正常(可能犯了一些愚蠢的错误或其他东西),但我认为一般的想法应该足以让你离开地面。希望这可以帮助!

于 2013-03-04T08:21:11.757 回答
1

在另一篇文章中找到了答案。问题是模板的处理使标签的“for”属性与输入元素的 id 元素匹配。这是帖子:

为 <label> 标签使用 Ember.js 文本字段 ID

我的解决方案:

App.BootstrapTextField = Ember.View.extend({
  displayLabel: null, 
  classNames: ['control-group'],

  template: Ember.Handlebars.compile('' +
              '<label class="control-label" {{bindAttr for="view.textField.elementId"}}>' +
              '{{view.displayLabel}} </label>' +
              '<div class="controls">{{view Ember.TextField valueBinding=view.value viewName="textField"}}</div>'
                                    ),
})

使用以下模板调用:

{{view App.BootstrapTextField valueBinding='somefield' displayLabel='FieldName'}}
于 2013-03-13T07:07:49.853 回答