通过关系访问ember-data的属性(不在模板中)

时间:2013-08-14 03:25:44

标签: properties ember.js parent-child ember-data has-many

我想强调这个问题只发生在模板之外,例如当我在控制器,单元测试等中尝试访问相关对象的属性时。渲染模板似乎很好地获得了属性并且工作为预期

以下是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");
});

这就像忘记一个角色或其他什么东西一样简单/愚蠢,但我想我已经让自己太过沮丧了一段时间才能清醒地思考。提前感谢您的帮助。

1 个答案:

答案 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