我有一个后端服务器(在node.js上运行),我使用Ember(v 2.0.2)和Ember-data(2.0.0)和JQuery(2.1.4)。 node.js有body-parser和express安装。前端库是Ember,Ember-data和JQuery
当我在 App.js 文件的 app.ContactsRoute 函数中使用 .findAll()方法获取数据时,我得到了Chrome开发者控制台中出现以下错误
处理路线时出错:联系人断言失败:您必须包含' id'对于传递给' push'的对象中的未定义错误:断言失败:您必须包含' id'对于传递给' push'的对象中的未定义 在新错误(本机)
本地主机网站链接还显示此错误,显示Ember-template-compiler和Ember-data行中的错误。由于在问题中发布超链接的限制,因此无法在问题中发布它
Server.js文件:
var express = require('express'),
bodyParser = require('body-parser'),
app=express();
var id = 7;
var data = {
1: {id:1, firstName: 'Danny', lastName: 'Stork', email: 'dannystork@example.com'},
2: {id:2, firstName: 'Carlotta', lastName: 'McOwen', email: 'carlottamcowen@example.com'},
3: {id:3, firstName: 'Luther', lastName: 'Ellery', email: 'lutherellery@example.com'},
4: {id:4, firstName: 'Finch', lastName: 'Hosky', email: 'finchhosky@example.com'},
5: {id:5, firstName: 'Carson', lastName: 'Andrews', email: 'carsonandrews@example.com'},
6: {id:6, firstName: 'Mac', lastName: 'Parker', email: 'macparker@example.com'},
7: {id:7, firstName: 'J.D.', lastName: 'Barney', email: 'jdbarney@example.com'},
};
app.use(bodyParser.json());
app.use(express.static('./public'));
app.route('/api/contacts')
.get(function(req,res){
res.json(Object.keys(data).map(function(key){
return data[key];
}));
})
.post(function(req,res){
var record = req.body
record.id = ++id;
data[record.id] = record;
res.json(record);
});
app.route('/api/contacts/:id')
.get(function(req,res){
res.json(data[req.params.id]);
})
.put(function(req,res){
data[req.params.id]=req.body;
res.json(req.body);
})
.delete(function(req,res){
delete data[req.params.id];
res.json(null);
});
app.get('*', function(req,res){
res.sendFile(__dirname + '/public/index.html');
});
app.listen(3000);
app.js文件:
var app = Ember.Application.create();
app.ApplicationAdapter = DS.RESTAdapter.extend({
namespace:'api'
});
app.Contact = DS.Model.extend({
firstName: DS.attr('string'),
lastName: DS.attr('string'),
email: DS.attr('string')
});
app.ContactSerializer = DS.RESTSerializer.extend({
extractArray: function(store, primaryType, payload){
payload ={contacts: payload} ;
return this._super(store,primaryType,payload);
},
extractSingle: function(store, primaryType, payload, recordId){
payload ={contact: payload} ;
return this._super(store,primaryType,payload,recordId);
},
serializeIntoHash: function(hash,type, snapshot,option){
var json = this.serialize(snapshot, {included:true});
Object.keys(json).forEach(function(key){
hash[key] = json[key];
});
}
});
//to get pushstate routes instead of hashbang routes - #!
//access the app.Router class and set the location
app.Router.reopen({
location: 'history'
});
//routes
app.Router.map( function(){
//this.resource used when there is a noun or object behind e.g. /contacts or /contact/:id
//this.route used when there is no noun or object behind it e.g. /contact/new (no existing data is present)
this.route('contacts');
this.route('contact',{path: 'contacts/:contact_id'});
this.route('new',{path: 'contacts/new'});
});
//this is used for the default route when it doesn't match any other routes in the above list of routes.
app.IndexRoute = Ember.Route.extend({
redirect: function(){
this.transitionTo('contacts');
}
});
app.ContactsRoute = Ember.Route.extend({
model: function() {
return this.store.findAll('contact');
}
})
的index.html:
<html>
<head>
<title> Ember Contacts </title>
<link rel='stylesheet' href='/style.css' />
<base href="/">
</head>
<body>
<!-- This is like the app class (here id = application is used) defined as top level template -->
<!-- This is common to all our pages -->
<script type='text/x-handlebars' id='application'>
<div id='main'>
<header>
<h1> {{#link-to 'contacts'}} Ember Contacts {{/link-to}}</h1>
</header>
<div id='app'>
{{outlet}}
</div>
</div>
</script>
<script type='text/x-handlebars' id='contacts'>
<div class='actions'>
{{#link-to 'new'}} NEW Contact {{/link-to}}
</div>
<ul>
{{#each contact in model}}
<li>
{{#link-to 'contact' contact}}
{{contact.firstName}} {{contact.lastName}} <span>{{contact.email}}</span>
{{/link-to}}
</li>
{{/each}}
</ul>
</script>
<script src='/lib/jquery/dist/jquery.min.js'></script>
<script src='/lib/ember/ember-template-compiler.js'></script>
<script src='/lib/ember/ember.debug.js'></script>
<script src='/lib/ember-data/ember-data.js'></script>
<script src='/app.js'></script>
</body>
</html>
有人可以帮忙解决这个问题吗?为什么这个错误会出现在ember-data中?
我是ember.js的新手,正在完成一个教程。我无法使用他在视频中使用的相同版本。因此使用了最新版本的Ember和Ember数据。
答案 0 :(得分:1)
我已经使它适用于最新版本。从您的代码中更改了以下内容:
在App.js :
内部app.ContactSerializer = DS.RESTSerializer.extend({
功能:
extractArray
函数已更改为新函数normalizeFindAllResponse
(请注意,更改此函数时参数也已更改)。该功能现在看起来像:
normalizeFindAllResponse: function(store, primaryModelClass, payload, id, requestType){
payload = {contacts: payload};
return this._super(store, primaryModelClass, payload, id, requestType);
},
extractSingle
函数已更改为新函数normalizeFindRecordResponse
(请注意,更改此函数时参数也已更改)。该功能现在看起来像:
normalizeFindRecordResponse: function(store, primaryModelClass, payload, id, requestType){
payload ={contact: payload} ;
return this._super(store, primaryModelClass, payload, id, requestType);
},
在Index.html 中,在<ul>
标记内,更改&#34; {{#each contact in model}}
&#34;到&#34; {{#each model as |contact|}}
&#34;。并删除Handlebars参考<script src='/lib/handlebars/handlebars.js'> </script>
。最新版本的Ember并不需要明确引用Handlebars。
希望这有所帮助,最好使用最新版本,因为这些变化非常适合推向新版本。