2013-10-08 231 views
5

我在使用NDB的Google App Engine項目中使用EmberJs和Ember-Data。在數據庫中,我有主機,探測和檢查實體。數據庫模式其實並不重要,只要我有我的REST API,以便但是爲了清楚這裏是我的數據庫類:Ember數據嵌套模型

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) 
]) 

http://example.com/hosts回報:

{ 
    "hosts": [ 
     { 
      "hostName": "SomeHostName1", 
      "id": "SomeHostId1" 
     }, 
     { 
      "hostName": "SomeHostName2", 
      "id": "SomeHostId2" 
     } 
    ] 
} 

http://example.com/hosts/SomeHostId1/probes回報:

{ 
    "probes": [ 
     { 
      "probeName": "SomeProbeName1", 
      "id": "SomeProbeId1", 
      "host_id": "SomeHostId1" 
     }, 
     { 
      "probeName": "SomeProbeName2", 
      "id": "SomeProbeId2", 
      "host_id": "SomeHostId1" 
     } 
    ] 
} 

http://example.com/hosts/SomeHostId1/probes/SomeProbeId1/checks回報:

{ 
    "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> 

現在我有這一切......但不知道如何配合它在一起,使灰燼,數據做出正確的HTTP要求。到目前爲止,我只看到請求去http://example.com/modelName/

回答

3

當前Ember數據不支持此類型的API端點的嵌套路由。有一些關於這個的討論,但它似乎沒有取得任何進展。

+0

嵌入式記錄和嵌套API路由是兩個完全不同的東西。 –

+0

我讓這個問題先得到更多的意見,然後接受你的答案。我只是增加了賞金才能獲得更多的關注。希望它有幫助;) –

+2

兩年後的任何更新? – Joe

3

我不知道App Engine的東西,但如果你能獲得這樣的配置,對於燼數據休息適配器

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) 
]) 

而且響應http://example.com/hosts應該返回一個JSON陣列的主機: {},{}]和http://example.com/hosts/1一個代表主機對象主機的json:{}和其他AppEngine路由相同

+0

一次加載所有支票可能是一個壞主意。爲了清楚起見,我保留了一層嵌套(checkDataItems)。我有一些情況,我們有超過1000個主機運行1+探測器運行15+次檢查。每個支票可以有1-20個數據項。 如果我只取得支票,它可能運行良好。但是,如果我然後一次加載checkDataItems以及...可能需要一段時間。 –

+1

您可以在查詢中添加參數,並使用諸如store.findQuery('check',{probe_id:「1」})之類的東西點擊http://example.com/checks?probe_id=1。然後在您的chechks中路線模型鉤子 – Edu

+0

這是我的備份實現。 –

2

您已經定義了Host模型兩次,我認爲不應該是這種情況。我非常新的餘燼和沒有使用異步:真正的功能,但我已經能夠做這樣的事情(但我沒有使用嵌套的路線):

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

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

App.Check = DS.Model.extend({ 
    checkName: DS.attr('string') 
}); 

,你可以旋轉起來休息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" 
     } 
    ] 
} 

在我來說,我沒有嵌套的路線,但我認爲我們應該能夠以某種方式設置爲從主負載控制器內容,因爲所有需要的內容都在店裏了!我不知道這是否有幫助,但這也是我想知道答案的。

+0

添加子實體的Id將花費我第二個數據庫查詢,因爲您無法(也不應該)在Google數據存儲中進行連接。但是,我認爲運行第二個查詢可能是可以接受的,因爲我只要求id屬性。 –

+0

PS你說得對,它應該是一個檢查模型。我已經更新了現在的帖子:) –

+0

我想在你的答案中做同樣的事情,我還沒有運行的代碼還沒有...控制器看起來像這樣?在ember文檔中的AFAICT控制器只代表一個模型類(單個對象或相同類型的列表) – Anentropic