Ember.js 余烬数据嵌套模型

Ember.js 余烬数据嵌套模型,ember.js,ember-data,Ember.js,Ember Data,我在一个使用NDB的Google应用程序引擎项目中使用了EmberJs和Ember数据。在数据库中,我有主机、探测和检查实体。只要我的REST api井然有序,数据库模型实际上并不重要,但为了清楚起见,以下是我的数据库类: class Host(ndb.Model): hostName = ndb.StringProperty() hostKey = ndb.Key('Host', 'SomeHostId') class Probe(ndb.Model): checkName

我在一个使用NDB的Google应用程序引擎项目中使用了EmberJs和Ember数据。在数据库中,我有主机、探测和检查实体。只要我的REST api井然有序,数据库模型实际上并不重要,但为了清楚起见,以下是我的数据库类:

class Host(ndb.Model):
    hostName = ndb.StringProperty()

hostKey = ndb.Key('Host', 'SomeHostId')

class Probe(ndb.Model):
    checkName = ndb.StringProperty()

probeKey = ndb.Key('Host', 'SomeHostId', 'Probe', 'SomeProbeId')

class Check(ndb.Model):
    checkName = ndb.StringProperty()

checkKey = ndb.Key('Host', 'SomeHostId', 'Probe', 'SomeProbeId', 'Check', 'SomeCheckId')
我添加这些键是为了显示每个主机上都有一些探测器在运行,并且每个探测器都执行一些检查

  • 主人
    • 探测
      • 检查
在我的App.Js中,我定义了以下模型:

App.Host = DS.Model.extend({
    hostName: DS.attr('string')
    probes: DS.hasMany('probe',{async:true})
});

App.Probe = DS.Model.extend({
    host: DS.belongsTo('host'),
    probeName: DS.attr('string')
    checks: DS.hasMany('check',{async:true})
});

App.Check = DS.Model.extend({
    probe: DS.belongsTo('probe'),
    hostName: DS.attr('string')
});
我定义了以下路由器:

App.Router.map(function() {
    this.resource('hosts', function(){
        this.resource('host', { path:':host_id'}, function(){
            this.resource('probes', function(){
                this.resource('probe', { path:':probe_id'}, function(){
                    this.resource('checks', function(){
                        this.resource('check', { path:':check_id'}, function(){

                        });
                    });
                });
            });
        });
    });
});
在AppEngine中,如果已构建以下URL路径:

app = webapp2.WSGIApplication([
    ('/', MainHandler),
    webapp2.Route('/hosts', HostsHandler),
    webapp2.Route('/hosts/<hostId>/', HostHandler),
    webapp2.Route('/hosts/<hostId>/probes', ProbesHandler),
    webapp2.Route('/hosts/<hostId>/probes/<probeId>/checks', ChecksHandler),
    webapp2.Route('/hosts/<hostId>/probes/<probeId>/checks/<checkId>/', CheckHandler)
])
返回:

{
    "hosts": [
        {
            "hostName": "SomeHostName1",
            "id": "SomeHostId1"
        },
        {
            "hostName": "SomeHostName2",
            "id": "SomeHostId2"
        }
    ]
}
{
    "probes": [
        {
            "probeName": "SomeProbeName1",
            "id": "SomeProbeId1",
            "host_id": "SomeHostId1"
        },
        {
            "probeName": "SomeProbeName2",
            "id": "SomeProbeId2",
            "host_id": "SomeHostId1"
        }
    ]
}
{
    "checks": [
        {
            "checkName": "SomeCheckName1",
            "id": "SomeCheckId1",
            "probe_id": "SomeProbeId1"
        },
        {
            "checkName": "SomeCheckName2",
            "id": "SomeCheckId2",
            "probe_id": "SomeProbeId1"
        }
    ]
}
返回:

{
    "hosts": [
        {
            "hostName": "SomeHostName1",
            "id": "SomeHostId1"
        },
        {
            "hostName": "SomeHostName2",
            "id": "SomeHostId2"
        }
    ]
}
{
    "probes": [
        {
            "probeName": "SomeProbeName1",
            "id": "SomeProbeId1",
            "host_id": "SomeHostId1"
        },
        {
            "probeName": "SomeProbeName2",
            "id": "SomeProbeId2",
            "host_id": "SomeHostId1"
        }
    ]
}
{
    "checks": [
        {
            "checkName": "SomeCheckName1",
            "id": "SomeCheckId1",
            "probe_id": "SomeProbeId1"
        },
        {
            "checkName": "SomeCheckName2",
            "id": "SomeCheckId2",
            "probe_id": "SomeProbeId1"
        }
    ]
}
我的模板是:

<script type="text/x-handlebars" id="host">
  <h3>{{hostName}}</h3>
  {{#link-to 'probes' probes}}probes{{/link-to}}

  {{outlet}}
</script>

<script type="text/x-handlebars" id="probes">
  {{#each probe in probes}}
    Probe: {{probe.probeName}}
    {{#link-to 'checks' probe.checks}}checks{{/link-to}}
  {{/each}}

  {{outlet}}
</script>

<script type="text/x-handlebars" id="checks">
  {{#each check in checks}}
    Check: {{check.checkName}}
  {{/each}}
</script>

{{hostName}}
{{{#链接到'probes'探针}}探针{{/link到}
{{outlet}}
{{#探针中的每个探针}
探测:{Probe.probeName}
{{{#链接到'checks'探测.checks}}检查{{/link to}
{{/每个}}
{{outlet}}
{{#每次签入都会签入}
检查:{{Check.checkName}
{{/每个}}

现在我有了所有这些。。。但不知道如何将其绑定在一起,以便Ember数据发出正确的http请求。到目前为止,我只看到请求转到

当前,Ember数据不支持API端点的这种嵌套路由。有人谈论过这一点,但它似乎没有取得任何进展。

我对应用程序引擎一无所知,但如果你能获得像这样的配置,对于ember data rest adapter

app = webapp2.WSGIApplication([
    ('/', MainHandler),
    webapp2.Route('/hosts', HostsHandler),
    webapp2.Route('/hosts/<hostId>', HostHandler),
    webapp2.Route('/probes', ProbesHandler),
    webapp2.Route('/probes/<probeId>', ProbesHandler),
    webapp2.Route('/checks/', CheckHandler)
    webapp2.Route('/checks/<checkId>/', CheckHandler)
])
app=webapp2.WSGIApplication([
(“/”,MainHandler),
webapp2.Route('/hosts',HostsHandler),
webapp2.Route('/hosts/',HostHandler),
webapp2.Route(“/probes”,ProbeHandler),
webapp2.Route(“/probes/”,ProbeHandler),
webapp2.Route('/checks/',CheckHandler)
webapp2.Route('/checks/',CheckHandler)
])

对的响应应该返回一个json数组hosts:[{},{}],并返回一个表示主机对象hosts:{}的json,对于其他AppEngine路由也是如此。您已经定义了两次主机模型,我认为不应该是这样。我是ember的新手,还没有使用async:true功能,但我已经能够做到(但我没有使用嵌套路由):

您还可以为主机启动一个rest api,该api返回:

{
    "hosts": [
        {
            "hostName": "SomeHostName1",
            "id": "SomeHostId1",
            "probes":["p1","p2"]
        },
        {
            "hostName": "SomeHostName2",
            "id": "SomeHostId2",
            "probes":["p2","p3"]
        }
    ],
    "probes": [
        {
            "probeName": "SomeProbeName1",
            "id": "p1",
            "checks":["c1","c2"]
        },
        {
            "probeName": "SomeProbeName2",
            "id": "p2",
            "checks":["c2","c3"]
        }
    ],
    "checks": [
        {
            "checkName": "SomeCheckName1",
            "id": "c1"
        },
        {
            "checkName": "SomeCheckName2",
            "id": "c2"
        }
    ]
} 

在我的例子中,我没有嵌套的路由,但我认为我们应该能够以某种方式从主负载设置控制器内容,因为所有必需的内容都已经存储在存储中了!我不知道这是否有帮助,但这也是我想知道的答案。

嵌入式记录和嵌套API路由是两件完全不同的事情。我让这个问题先获得更多视图,然后接受您的答案。我加上赏金只是为了引起更多的注意。希望能有所帮助;)一次装入所有支票可能不是一个好主意。为了清晰起见,我保留了一层嵌套(checkDataItems)。我遇到过这样的情况,1000多台主机运行1台探测器运行15台以上的检查。每次检查可以有1-20个数据项。如果我只得到支票,它可能运行正常。但是如果我同时加载checkDataItems。。。这可能需要一段时间。您可以将参数添加到查询中,然后使用类似store.findQuery('check',{probe_id:'1})的命令。然后()在您的chechks路由模型hookyea中,这是我的备份实现。添加子实体的id将花费我第二次数据库查询,因为您不能(也不应该这样做)加入谷歌数据存储。但是,我认为运行第二个查询可能是可以接受的,因为我只要求id属性。如果您是对的,它应该是一个检查模型。我现在已经更新了帖子:)我正在尝试和你的答案一样,我还没有运行代码。。。这个控制器看起来像什么??ember文档中的AFAICT控制器仅代表一个模型类(单个对象或相同类型的列表)。给定的json结构将是HugsController(ArrayController)的基础模型/内容,因此json结构包含多个主机(以及与之相关的所有探测/检查)。如果您考虑的是单个主机,那么您将创建一个HostController,它将是一个ObjectController,而底层json(模型)将是{“主机”:{“主机名”:…,“probles”:[“p1”,“p2”]},“探测”:[{“id”:“p1”,…},{“id”:“p2”,…}]}}。希望你能拿到jist。