2013-11-20 22 views
15

私は過去数時間この問題に苦労しています。私は請求書を作成するためのemberアプリケーションを作成しています。私はキーボードを使用してフィールドを変更するには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'}} 

アクションが異なる場所にある場合(これはコンポーネントなので、別の場所では異なる意味を持つ可能性があります)。また、アクション/トリガーされたアクションの衝突も回避します。あなたはでしょうコンポーネントの2つのインスタンスを持つことのアイデアを考え、それぞれがコントローラ内の異なるアクションをトリガーする

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

にあなたのケースで、あなただけの

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

を書くことができ、あなたのコンポーネントの内部

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

コンポーネントのように内蔵されていても構わないと思うのであれば、コンポーネントではなくビューを使用するとよいでしょう。あなたはヘルパーとしてそれを登録することができ、それはきれいに見えるでしょう。それは常に同じであり、あなたはあなたの成分を含むの構文を簡素化したい場合は、コンポーネントの中に、あなたのアクションの名前を定義することができます@ Kingpin2kにより、素敵な答えに加えとして

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

    actions: function(){ 
    // etc etc 
    } 

})); 

{{edit-item}} 
+1

これは私の問題を解決しました。私はこの背後にあるコンセプト(自己完結型のコンポーネント)を理解していますが、これは私のケースではコードの繰り返しを導入しています。 – Wilhearts

+0

自己完結型であることに気をつけなければ、ビューは簡単かもしれません – Kingpin2k

+0

テンプレートの引用符は**本当に重要**です。 – 0xcaff

2

。すなわち、この例では

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方法を使用します。たとえば、いくつかの選択入力を含むコンポーネントの変更をナビゲートするか、一般的にコンポーネント内からルートを変更するだけです。

関連する問題