【问题标题】:Using Ember.js text field ids for a <label> tag为 <label> 标签使用 Ember.js 文本字段 ID
【发布时间】:2012-05-15 03:20:44
【问题描述】:

标签标签的格式为:

<label for="id_of_text_field">
<input type="text" name="example" id="id_of_text_field" />

其中标签的for标签和文本字段的id标签需要匹配。我有两个想法可以在我的 Ember.js 模板中完成这项工作:

想法 #1: 我尝试创建一个名为 field_id 的特殊绑定,以便在 labelTextField 中使用。我执行如下:

<label {{bindAttr for="content.field_id"}}> {{content.label}}</label>
{{view Ember.TextField valueBinding="content.data" id="content.field_id"}}

不幸的是,只有label's id 可以正确呈现。 TextField's id 确实正确渲染,结果显示为“metemorph ... something-or-other”。

想法 #2: 以某种方式变出 TextField 的 id 并将其用于标签标签,但恐怕在某些时候 TextField 的 id 在呈现标签标签时不会准备好。即使这不是问题,我也不知道如何从 JS 中找到 TextField's id。

这是在模板中,因此我将拥有多个标签/文本字段对。

如何让标签的 for 标签与带有 Ember.js 的 TextField 的 id 标签匹配?

谢谢!

更新

根据 Peter Wagenet 的建议并稍作修改,我做了以下工作:

<label {{bindAttr for="textField.elementId"}}> {{content.label}}</label>
{{view Ember.TextField valueBinding="content.value" viewName="textField"}}

使用此技术,用户现在可以单击标签来选择 TextFields、CheckBoxes 和 Selects。

【问题讨论】:

  • 对于最新的 Ember (1.4.0-beta.6),您需要改用 for="view.textField.elementId"

标签: templates ember.js


【解决方案1】:

首先,Metamorph 标签用于标签的值。它与字段的 id 无关。但是,此代码仍然无法工作,因为标准属性不会对属性路径做任何特殊的事情。在这种情况下,id 的值实际上是 content.field_id。这肯定不是你想要的。在正常情况下,您可以使用elementIdBindingid 只是elementId 的别名),但是 Ember Views 的元素 ID 在创建后无法更改,因此该方法在这里不起作用。

一种可能的解决方案是使用viewName 属性。 viewName 属性提供对parentView 上视图的命名引用。然后,您可以执行以下操作:

<label {{bindAttr for="view.textField.field_id"}}> {{content.label}}</label>
{{view Ember.TextField valueBinding="content.data" viewName="textField"}}

【讨论】:

  • 我认为jsfiddle.net/GtsKK/2 充分展示了 shs 的用途。您希望将“for”绑定到 textField.elementId,而不是 field_id,因为 TextField 视图没有该属性。此外,您不能只单独使用 TextField 类,因为它的 name 属性不绑定任何内容,并且为了使其成为有效的表单,您必须为每个输入提供一个名称,所以我将其子类化TextField 并添加了缺少的名称属性绑定。
  • 抱歉编辑...所以我将模板设置为:{{查看 Ember.TextField valueBinding="content.data" viewName="textField"}} 就是这样。 forid 标签现在匹配了。不需要 JS。很不错!我将您的“field_id”更改为“elementId”。似乎太容易了。
  • 出于好奇,我如何从 content.field_id 计算值中获取“parentView”?从内部 field_id: function() {} 我尝试了各种 get|getPath() 和 'view'、'this.view'、'parentView'、'this.parentView',它们都返回 null 或 undefined。
  • @shs 如果你能提供一个你正在尝试做的事情,那会有所帮助。
  • @DarylTeo 如果您仍在寻找解决方案,请尝试将 {{#each}} 块替换为 {{#collection}} 块,如下所示:jsbin.com/ufevoh/7/edit
【解决方案2】:

这是我不久前对这个问题的解决方案:

App.Widget.TextField = Em.ContainerView.extend({
    tagName: '',
    type: 'text',
    label: null,
    value: null,
    valueSize: '30px',

    childViews: ['labelView', 'inputView'],

    labelView: Em.View.extend({
        tagName: 'label',
        attributeBindings: ['for'],

        forBinding: 'parentView.inputView.elementId',

        init: function () {
            this.set('defaultTemplate', Em.Handlebars.compile(this.getPath('parentView.label')));
            this._super();
        }
    }),

    inputView: Em.TextField.extend({
        typeBinding: 'parentView.type',
        sizeBinding: 'parentView.valueSize',
        valueBinding: 'parentView.value'
    })
});

然后从 Handlebars 模板中:

{{view App.Widget.TextField label="Some Label"}}

【讨论】:

    【解决方案3】:

    这并不总能解决您的问题,但我只想补充一点,简单地将输入嵌套在标签内通常是一种方便的解决方案,因为它允许您完全删除 for 属性 (reference)。

    【讨论】:

    • 有趣。我正计划在表格中布置控件,其中一列中的标签和另一列中的控件。
    • 你知道浏览器对此的支持是什么吗?通过快速试用,它似乎在 Firefox 和 Chrome 中运行良好。我手边没有IE...
    • 我不知道。不过,这似乎是一种常见的模式,所以我认为它得到了广泛的支持。
    猜你喜欢
    • 2016-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-27
    • 2014-09-13
    • 2012-05-31
    相关资源
    最近更新 更多