2013-01-02 48 views
1

下面的代碼工作正如我所期望的那樣,我可以通過content.dev.name訪問environments模板中的數據。遠程AJAX數據到控制器

雖然我正在努力通過AJAX請求填充這些數據。

我有一個rest API,它返回下面控制器中的結構。它在加載應用程序時需要調用一次。

這是我工作的代碼:

控制器

App.EnvironmentsController = Ember.Controller.extend(); 
App.EnvironmentsController.reopenClass({ 
    find: function(){ 
    return {dev: {key: 'dev', name: 'Development'}, prod: {key: 'prod', name: 'Production'}}; 
    return this.content; 
    }, 
}); 
App.EnvironmentsView = Ember.View.extend({ 
    templateName: 'environments' 
}); 

路線

... 
router.get('applicationController').connectOutlet('environments', App.EnvironmentsController.find()); 
... 

模板

<script type="text/x-handlebars" data-template-name="environments"> 
    <ul id="env-menu"> 
     {{#with content}} 
     <li>{{dev.name}}</li> 
     <li>{{prod.name}}</li> 
     {{/with}} 
    </ul> 
    </script> 

這裏是用AJAX控制,我不能讓數據通過相同格式的模板。

注意:我知道response.data.environments本身返回的結構與我上面手動編碼的對象相同。

App.EnvironmentsController = Ember.Controller.extend(); 
App.EnvironmentsController.reopenClass({ 
    environments: {}, 
    find: function(){ 
    $.ajax({ 
     url: 'http://localhost:3000/environments', 
     dataType: 'json', 
     context: this, 
     success: function(response){ 
     this.environments = response.data.environments; 
     } 
    }); 
    return this.environments; 
    }, 
}); 
App.EnvironmentsView = Ember.View.extend({ 
    templateName: 'environments' 
}); 

注意,我有一些類似的工作時,控制器是一個陣列控制器,以及數據被作爲一個數組返回。我需要知道如何使這個對象專門工作。

更新:從問題

更多資訊是一個小提琴:http://jsfiddle.net/coder1/csvZX/

我開出了不同的模式。我只是試圖繞過我的頭,通過和獲取對象並通過控制器發送它。

這是一個非常了不起的教程(http://trek.github.com/)我開始使用,我可以使用數組控制器工作,而不是在使用單個對象時。

+0

'App.EnvironmentsController.find()'不會返回AJAX請求的結果,因爲'A'jax是'A'syncronous。 – sabithpocker

+0

使用'set'和'get','this.set('environments',response.data.environments);' – sabithpocker

+0

是的,我開始使用本教程,其工作原理如下:http://trek.github.com/ ..我想知道同樣的事情,但它的工作。引用:'App.Contributor.find()' – Coder1

回答

4

我調整你的jsfiddle,它現在可以正確顯示數據。

關鍵是數據是由模型處理的,而不是控制器。我修改了原來的jsfiddle,並將數據加載部分分成了一個類,負責在find()函數中創建自己的實例。這和Trek的例子一樣。

新型號代碼:

App.Environments = Ember.Object.extend({ 

}); 
App.Environments.reopenClass({ 
    find: function() { 
     var env = App.Environments.create({}); 
     console.log("environments find()"); 
     // simulate an ajax call, hard coding response below 
     setTimeout(function() { 
      // Fake response 
      console.log("fake ajax response"); 
      console.log(env); 
      env.setProperties({ 
       dev: { 
        key: 'dev', 
        name: 'Development' 
       }, 
       prod: { 
        key: 'prod', 
        name: 'Production' 
       } 
      }); 
      console.log(env); 
     }, 1000); 
     return env; 
    } 
}); 

假Ajax調用谷歌沒有工作,所以我換出來,並用一個setTimeout()調用模擬Ajax調用的延遲。

請注意,find()方法會創建一個新的Environments對象,然後讓fake-ajax調用將其填充數據。 find()立即返回新創建的空的Environments對象,該對象由控制器和模板訪問。 setProperties()方法用於以Ember的綁定系統可以檢測到更改並確保它們傳播到模板中的方式來更新此屬性。

唯一的另一件事是更新connectOutlets使用新Environments模型和:

router.get('applicationController').connectOutlet('environments', App.Environments.find()); 

這行代碼調用find(),返回新創建Environments對象,並把它傳遞給EnvironmentsController的實例控制器,並使用EnvironmentsView視圖填充application模板中的{{outlet}}

請確保檢查出工作jsfiddle示例。

1

在我的觀察,你正在做的可能的錯誤是:

  1. this.environments = response.data.environments;應該使用setaddObject什麼灰燼方式。

  2. 如果您使用變量environment而不是content也可以在模板中使用它。

這裏是一個小提琴http://jsfiddle.net/csvZX/17/

+0

我想你已經幫我縮小了問題的範圍:你如何異步設置非數組控制器的內容? addObject適用於數組,但不適用於對象變量。 – Coder1

+0

如果內容是ArrayController中的對象數組,我們使用'addObject'。對於像你這樣的簡單情況,我們使用'set'來設置值並'get'來獲取值。如果你使用set,它會更新變量。如果你使用'set('environments',{..blahblah ..})'它會更新'environments'而不是'content'。 'content'只是Ember用來存儲內容的一個變量。 – sabithpocker

+0

如果您可以製作小提琴,有人可以查看它。 – sabithpocker