2013-11-20 27 views
15

過去幾個小時我一直在爲此付出努力,我正在創建一個用於創建發票的ember應用程序。我使用的是組件(文本框)來修改字段使用鍵盤,但由於行動沒有發回到相關的控制器,我不能保存記錄在focusOut或insertNewLine並沒有發生。我使用:Ember組件sendAction()不起作用

Ember  : 1.1.2 
Ember Data : 1.0.0-beta.3 
Handlebars : 1.0.0 
jQuery  : 1.9.1 

這應該是這樣的:https://dl.dropboxusercontent.com/u/7311507/embercomponent.png

的問題似乎在於控制器或組件內,看來我失去了一些東西。

的執行console.log函數被調用的組件上,在sendAction電話永遠不會奏效......

感謝您的幫助。

ItemsRoute

App.ItemsRoute = Ember.Route.extend({ 
    renderTemplate: function() { 
      // Render default outlet 
      this.render(); 
      // render extra outlets 
      this.render("client", { outlet: "client", into: "application"}); 
     }, 
     model: function() { 
     return this.store.find('item'); 
     } 
    }); 

上述ItemsController

App.ItemsController = Em.ArrayController.extend({ 
    actions: { 
     createItem: function() { // NEVER GETS CALLED FROM COMPONENT 
     var title = "Nouvel élément" 

     // Create the new Todo model 
     var item = this.store.createRecord('item', { 
      desc: title, 
      qty: 1, 
      price: 0 
     }); 

     // Save the new model 
     item.save(); 
     } 
    }, 
    totalCount: function(){ 
     var total = 0; 
     this.get('model').forEach(function(item){ 
      total += item.get('totalprice'); 
     }); 
     return total; 
    }.property('@each.qty', '@each.price') 
}); 

ItemController

App.ItemController = Em.ObjectController.extend({ 
    didInsertElement: function(){ 
     this.$().focus(); 
    }, 
    actions: { 
     testAction: function(){ // NEVER GETS CALLED FROM COMPONENT 
      console.log("controller recieved call for testAction"); 
     }, 
     saveItem: function(value) { 
      this.get('model').save(); 

     }, 
     removeItem: function() { 
      var item = this.get('model'); 
      item.deleteRecord(); 
      item.save(); 
      }, 
    }, 
    isHovering: false 
}); 

項目模板

<script type="text/x-handlebars" data-template-name="items"> 
     <!-- ... --> 

     <tbody> 
     {{#each itemController="item"}} 
     {{view App.ItemView }} 
     {{/each}} 
     </tbody> 

     <!-- ... --> 
    </script> 

ItemView控件模板

<script type="text/x-handlebars" data-template-name="item"> 
    <td class="desc">{{edit-item value=desc}}</td> 
    <td class="qty">{{edit-item-number value=qty }}</td> 
    <td class="">{{edit-item-number step="25" value=price}}</td> 
    <td class="totalprice"> 
     {{ totalprice }} 
     <div class="delete-item" {{bindAttr class="isHovering"}} {{action "removeItem" on="click"}}> 
     <i class="icon-trash"></i> 
     </div> 
    </td> 
    </script> 

查看/組件

App.ItemView = Em.View.extend({ 
    templateName: "item", 
    tagName: "tr", 

    mouseEnter: function(event) { 
     this.get('controller').set('isHovering', true); 
    }, 
    mouseLeave: function(event) { 
     this.get('controller').set('isHovering', false); 
    } 
}); 

App.EditItem = Em.TextField.extend({ 
    becomeFocused: function() { 
     this.$().focus(); 
    }.on('didInsertElement'), 

    insertNewline: function(){ 
     console.log('Tried to insert a new line'); // WORKS 
     this.triggerAction('createItem'); // DOESN'T WORK 
    }, 

    focusOut: function(){ 
     console.log('Focused the Field Out') // WORKS 
     this.triggerAction('testAction', this); // DOESN'T WORK 
    } 

}); 

App.EditItemNumber = App.EditItem.extend({ 
    becomeFocused: null, 
    attributeBindings: ["min", "max", "step"], 
    type: "number", 
    min: "0" 
}); 

Ember.Handlebars.helper('edit-item', App.EditItem); 
Ember.Handlebars.helper('edit-item-number', App.EditItemNumber); 

回答

33

你應該定義那裏的行動將確定在模板中的組件時發送。

{{edit-item value=desc createItem='someactionoutside'}} 

這是萬一行動在不同地方有不同的名稱(因爲這是一個組件,它可能在不同的位置有不同的含義)。它還避免了衝突動作/觸發動作。認爲有分量的兩個實例,的想法,每個人應觸發在您的情況下,控制器

{{edit-item value=desc createItem='createUser'}} 
{{edit-item value=desc createItem='createShoppingCart'}} 

不同的動作,你可以只寫

{{edit-item value=desc createItem='createItem'}} 

而且你的組件內部,你會請致電

this.sendAction('createItem', param1, param2, ....); 

如果您不關心它是否像組件一樣自包含,那麼您可能只想使用視圖而不是組件。你可以把它註冊爲幫手,它看起來也很漂亮。

Em.Handlebars.helper('edit-item', Em.View.extend({ 
    templateName: 'some_template', 

    actions: function(){ 
    // etc etc 
    } 

})); 

{{edit-item}} 
+1

多謝,這解決了我的問題,我理解這背後的概念(該組件是自包含的),但我的情況下,這將引入代碼的重複。 – Wilhearts

+0

如果您不關心自我包裝,視圖可能會更容易 – Kingpin2k

+0

另請注意,模板中的引號非常重要。 – 0xcaff

2

作爲除了漂亮的答案被@ Kingpin2k你也可以在組件中定義動作的名稱,如果它始終是相同的,要簡化包括您的組件的語法。即。

import Ember from 'ember'; 
export default Ember.Component.extend(SchoolPlayerProspectMixin, { 

    //Here we define an attribute for a string that will always be the same 
    transitionToRoute: "transitionToRoute", 

    somethingChanged: function(){ 
     console.log("OMG something changed, lets look at a post about it!"); 

     //Here we are passing our constant-attribute to the sendAction. 
     self.sendAction('transitionToRoute', "post.show", post); 

    }.observes('changableThing'), 
}); 

在此示例中,組件使用父控制器的transitionToRoute方法更改路由,即使組件可能不是按鈕/鏈接。例如,瀏覽包含多個選擇輸入的組件的更改,或僅更改組件內的路由。