Ember.js 方法无效后如何在模板中显示错误消息

Ember.js 方法无效后如何在模板中显示错误消息,ember.js,ember-data,Ember.js,Ember Data,我正在使用Ember.js显示客户列表。在这个模板中,我有一个创建新客户的模式。现在,当创建无效客户(例如,重复名称)时,错误应该显示在模板中。我怎样才能让它工作 型号 Docket.Customer = DS.Model.extend({ name: DS.attr('string'), initial: DS.attr('string'), description: DS.attr('string'), errors: {}, becameInval

我正在使用Ember.js显示客户列表。在这个模板中,我有一个创建新客户的模式。现在,当创建无效客户(例如,重复名称)时,错误应该显示在模板中。我怎样才能让它工作

型号

Docket.Customer = DS.Model.extend({
  name:        DS.attr('string'),
  initial:     DS.attr('string'),
  description: DS.attr('string'),
  errors: {},
  becameInvalid: function(errors) {
    this.set('errors', errors.get('errors'));
    console.log(this.get('errors'));
  }
});
Docket.Customer = DS.Model.extend({
  name:        DS.attr('string'),
  initial:     DS.attr('string'),
  description: DS.attr('string'),
  number:      DS.attr('string'),
  archived:    DS.attr('boolean')
});
控制台输出

模板

<h1>Customers<button data-uk-modal="{target:'#customer-modal'}" class="icon-plus">New customer</button></h1>

    <div id="customer-modal" class="uk-modal">
        <div class="uk-modal-dialog uk-modal-dialog-slide">
            <a class="uk-modal-close uk-close"></a>
            <form class="uk-form" {{action "save" on="submit"}}>
                <fieldset>
                    <legend>New customer</legend>
                    <div class="uk-form-row">
                        {{view Ember.TextField valueBinding="name" name="name" class="uk-width-1-1" placeholder="Name" required="" }}
                        {{#if errors}}foo{{/if}}
                        {{#if errors.name}}{{errors.name}}{{/if}}
                    </div>
                    <div class="uk-form-row">
                        {{view Ember.TextField valueBinding="initial" name="initial" class="uk-width-1-1" placeholder="Initial" required="" }}
                    </div>
                    <div class="uk-form-row">
                        {{view Ember.TextArea valueBinding="description" name="description" class="uk-width-1-1" placeholder="Description"}}
                    </div>
                    <div class="uk-form-row">
                        <button type="submit" class="icon-check">Save</button>
                    </div>
                </fieldset>
            </form>
        </div>
    </div>

    <ul class="entries">
    {{#each}}
       <li>
           <div class="actions">
               <button {{action "remove" id}} class="icon-close"></button>
           </div>
           <div class="link" {{action "edit" id}} data-uk-modal="{target:'#customer-modal'}">
                <span class="initial">{{initial}}</span>{{name}}
            </div>
       </li>
    {{else}}
        <li>No customers</li>
    {{/each}}
    </ul>
model: function() {
  this.store.find('customer');
  return this.store.filter('customer', function(customer) {

    // prevent Ember to insert new elements to the DOM if they are invalid
    // .get('isValid') returns always true, I think this is a bug, so I'm checking the ID
    return customer.get('id')
  })
}
{{#if errors}}{{errors.name}}{{/if}}
客户新客户
新客户
{{view Ember.TextField valueBinding=“name”name=“name”class=“uk-width-1-1”placeholder=“name”required=”“}
{{{if errors}}foo{{/if}
{{#if errors.name}{{errors.name}{{{/if}}
{{view Ember.TextField valueBinding=“initial”name=“initial”class=“uk-width-1-1”placeholder=“initial”required=”“}
{{view Ember.TextArea valueBinding=“description”name=“description”class=“uk-width-1-1”placeholder=“description”}
拯救
    {{{#各}
  • {{initial}}{{name}
  • {{else}
  • 没有顾客
  • {{/每个}}

> p>您应该考虑将验证移至控制器< /C>。表单验证和验证通常都是基于上下文的<代码>客户
型号可能具有不同的验证集,具体取决于您所处的应用程序的哪个部分

如果您决定将验证移动到
控制器
,则需要创建一个观察者来观察特定属性的更改,并相应地运行验证

注意:我所说的是客户端验证(不涉及在满足验证条件之前与服务器对话),而不是服务器端验证

App.CustomerController = Ember.ObjectController.extend({
  errors: [],
  runNameValidation: function() {
    // run validations for 'name'
    // if validations fail, push error to 'errors' array
    // on the controller
  }.observes('model.name')
});
有一种方法可以为您处理它(它将验证位抽象出来,并将其包装到验证混合中,以便更好地重用)。此外,如果您具体使用表单,则应考虑查看./P> 更新:

如果要使用服务器端验证,则需要添加到模板中的所有内容包括:

{{model.errors}}

当您尝试保存ED模型,但it服务器无法执行此操作时,
模型
将出现
错误
数组,您可以使用该数组。另外,我建议创建
错误
组件,而不是创建
错误
辅助对象。

您可以创建自定义把手辅助对象,如下所示:

Ember.Handlebars.helper('show-errors', function(errors) {
    var html = '';
    if (errors) {        
        html += '<ul>';
        $.each(errors, function(key, values) {
            html += '<li>' + key + ' - ' + values.join(',') + '</li>'
        });
        html += '</ul>'
    }    
    return html.htmlSafe();
})
Ember.handlebar.helper('show-errors',函数(errors){
var html='';
如果(错误){
html+='
    '; $.each(错误、函数(键、值){ html+='
  • '+key+'-'+values.join(',')+'
  • ' }); html+='
' } 返回html.htmlSafe(); })
因此,只需在某些模板中使用
{{show errors recordInstance.errors}
即可使用它

首先,没有错误,因此不会显示任何内容。当记录有错误时,
错误
哈希将被填充,模板将被更新

看看这把小提琴

我猜出来了:

设置

  • 余烬1.2.0
  • 余烬数据1.0.0-beta.4+金丝雀.7af6fcb0
  • 车把1.1.2运行时
型号

Docket.Customer = DS.Model.extend({
  name:        DS.attr('string'),
  initial:     DS.attr('string'),
  description: DS.attr('string'),
  errors: {},
  becameInvalid: function(errors) {
    this.set('errors', errors.get('errors'));
    console.log(this.get('errors'));
  }
});
Docket.Customer = DS.Model.extend({
  name:        DS.attr('string'),
  initial:     DS.attr('string'),
  description: DS.attr('string'),
  number:      DS.attr('string'),
  archived:    DS.attr('boolean')
});
控制器

var _this = this;

// Create new record
var customer = this.store.createRecord('customer', data);

// Check for server errors (422) when saving
customer.save().then(function(){
  _this.resetAndCloseForm(form);
}, function(response){
  _this.set('errors',response.errors);
});
路线

<h1>Customers<button data-uk-modal="{target:'#customer-modal'}" class="icon-plus">New customer</button></h1>

    <div id="customer-modal" class="uk-modal">
        <div class="uk-modal-dialog uk-modal-dialog-slide">
            <a class="uk-modal-close uk-close"></a>
            <form class="uk-form" {{action "save" on="submit"}}>
                <fieldset>
                    <legend>New customer</legend>
                    <div class="uk-form-row">
                        {{view Ember.TextField valueBinding="name" name="name" class="uk-width-1-1" placeholder="Name" required="" }}
                        {{#if errors}}foo{{/if}}
                        {{#if errors.name}}{{errors.name}}{{/if}}
                    </div>
                    <div class="uk-form-row">
                        {{view Ember.TextField valueBinding="initial" name="initial" class="uk-width-1-1" placeholder="Initial" required="" }}
                    </div>
                    <div class="uk-form-row">
                        {{view Ember.TextArea valueBinding="description" name="description" class="uk-width-1-1" placeholder="Description"}}
                    </div>
                    <div class="uk-form-row">
                        <button type="submit" class="icon-check">Save</button>
                    </div>
                </fieldset>
            </form>
        </div>
    </div>

    <ul class="entries">
    {{#each}}
       <li>
           <div class="actions">
               <button {{action "remove" id}} class="icon-close"></button>
           </div>
           <div class="link" {{action "edit" id}} data-uk-modal="{target:'#customer-modal'}">
                <span class="initial">{{initial}}</span>{{name}}
            </div>
       </li>
    {{else}}
        <li>No customers</li>
    {{/each}}
    </ul>
model: function() {
  this.store.find('customer');
  return this.store.filter('customer', function(customer) {

    // prevent Ember to insert new elements to the DOM if they are invalid
    // .get('isValid') returns always true, I think this is a bug, so I'm checking the ID
    return customer.get('id')
  })
}
{{#if errors}}{{errors.name}}{{/if}}
模板

<h1>Customers<button data-uk-modal="{target:'#customer-modal'}" class="icon-plus">New customer</button></h1>

    <div id="customer-modal" class="uk-modal">
        <div class="uk-modal-dialog uk-modal-dialog-slide">
            <a class="uk-modal-close uk-close"></a>
            <form class="uk-form" {{action "save" on="submit"}}>
                <fieldset>
                    <legend>New customer</legend>
                    <div class="uk-form-row">
                        {{view Ember.TextField valueBinding="name" name="name" class="uk-width-1-1" placeholder="Name" required="" }}
                        {{#if errors}}foo{{/if}}
                        {{#if errors.name}}{{errors.name}}{{/if}}
                    </div>
                    <div class="uk-form-row">
                        {{view Ember.TextField valueBinding="initial" name="initial" class="uk-width-1-1" placeholder="Initial" required="" }}
                    </div>
                    <div class="uk-form-row">
                        {{view Ember.TextArea valueBinding="description" name="description" class="uk-width-1-1" placeholder="Description"}}
                    </div>
                    <div class="uk-form-row">
                        <button type="submit" class="icon-check">Save</button>
                    </div>
                </fieldset>
            </form>
        </div>
    </div>

    <ul class="entries">
    {{#each}}
       <li>
           <div class="actions">
               <button {{action "remove" id}} class="icon-close"></button>
           </div>
           <div class="link" {{action "edit" id}} data-uk-modal="{target:'#customer-modal'}">
                <span class="initial">{{initial}}</span>{{name}}
            </div>
       </li>
    {{else}}
        <li>No customers</li>
    {{/each}}
    </ul>
model: function() {
  this.store.find('customer');
  return this.store.filter('customer', function(customer) {

    // prevent Ember to insert new elements to the DOM if they are invalid
    // .get('isValid') returns always true, I think this is a bug, so I'm checking the ID
    return customer.get('id')
  })
}
{{#if errors}}{{errors.name}}{{/if}}

谢谢,但我需要在我的模型中使用此方法,因为这是从API中查看422个错误的唯一方法。或者,如果触发了
becameInvalid
,我应该调用模型中的控制器方法吗?您可能应该观察模型的
becameInvalid
状态,并在控制器级别触发操作。但是我如何从模型中调用
runnamevalization
方法呢?我可以在一个观察者中组合多个验证吗?您不需要从您的模型运行
runnamevalization
runNameValidation
是一个观察者,在模型的属性发生更改时,该观察者会被激发。我尝试将{{customer.errors}}添加到我的模板中,但这不会改变任何内容。谢谢,但它对我不起作用(不知道为什么)。但我发现了(见下面的答案):)