我想强调这个问题只发生在模板之外,例如当我在控制器,单元测试等中尝试访问相关对象的属性时。渲染模板似乎很好地获得了属性并且工作为预期
以下是JS Bin中的一个简单示例,其中包含一个失败的测试http://jsbin.com/ihumuk/4/edit,它可以解决我的问题。传递测试声明该属性可以按预期在模板中访问和呈现。失败的测试表明,当我尝试使用null
访问该属性时,我得到get
。这里真的没什么特别的,但我不明白为什么它会回归null
。
以下是JS Bin示例的应用程序部分:
App.ApplicationRoute = Em.Route.extend({
model: function() {
return App.Foo.find();
}
});
App.Store = DS.Store.extend({
adapter: DS.FixtureAdapter.create()
});
App.Foo = DS.Model.extend({
name: DS.attr("string"),
/**
* The subject under test
*/
childName: function() {
return this.get("child.name");
}.property("child.name"),
child: DS.belongsTo("App.Bar")
});
App.Bar = DS.Model.extend({
name: DS.attr("string")
});
App.Foo.FIXTURES = [{
id: 1,
name: "Fred",
child: 3
}, {
id: 2,
name: "Barney",
child: 4
}];
App.Bar.FIXTURES = [{
id: 3,
name: "Pebbles"
}, {
id: 4,
name: "Bam Bam"
}];
这传递了。
test("Child name is rendered", function() {
expect(1);
visit("/").then(function() {
ok(find("div:contains(Pebbles)").length);
});
});
这失败了。
test("Child name is accessed", function() {
expect(2);
var foo = App.Foo.find(1);
equal(foo.get("childName"), "Pebbles");
equal(foo.get("child.name"), "Pebbles");
});
这就像忘记一个角色或其他什么东西一样简单/愚蠢,但我想我已经让自己太过沮丧了一段时间才能清醒地思考。提前感谢您的帮助。
答案 0 :(得分:2)
您需要使用then
来了解数据的加载时间
asyncTest("Child name is accessed", function() {
expect(2);
// load the data from server
App.Foo.find(1).then(function(foo) {
// the child id is 3, we need to fetch the remaining data
// and this is async, because of the ajax request
foo.get("child").then(function(child) {
equal(child.get("name"), "Pebbles");
// childName call child.name, but since the
// data is loaded, isn't necessary to use a second then
equal(foo.get("childName"), "Pebbles");
start();
});
});
});
在ember数据中,就像orm的主要数据一样,数据是延迟加载的,用于关系。这是因为,不需要返回所有加载的对象图,让我们让用户询问它想要什么,然后加载。
因为某些实现是异步的,例如:websql,indexeddb,ajax,websockets等。ember-data的接口是异步的,所以你需要使用then
方法知道数据加载或失败的时间
这些东西在你的模板中起作用,因为它具有绑定意识。即使更改是异步的,它也会在稍后完成,并且将通知和更新绑定。
我已更新您的演示版,测试通过http://jsbin.com/eqojaj/1/edit