0
votes

I am creating one ember app. Flow is like " page1 displays list of feeds item and clicking on any of the feed will take user to page2 showing details about that feed"

What i am doing: i have one component named app-feed. Template is as below

<div onclick={{action 'click' feed}}>
{{#paper-card class="card-small" as |card|}}
  <!--  <a href="feed/{{feed.id}}"> --> {{card.image src=feed.imagePath class="small-feed-img" alt=feed.title}}<!--</a>-->
    {{#card.header class="flex-box short-padding" as |header|}}
            {{#header.avatar}}
                <img class="profile-small"  src="http://app.com/users/{{feed.userName}}.jpg" alt="{{feed.name}}" />
            {{/header.avatar}}
            <span class="tag-sm like-box">
                {{feed.likes}} {{paper-icon "thumb_up" size="18"}}
                {{feed.commentCount}}{{paper-icon "chat_bubble"  size="18"}}
            </span>
    {{/card.header}}
    {{#card.actions class="action-block"}}
        {{#paper-button iconButton=true}}{{paper-icon "favorite" size="18"}}{{/paper-button}}
        {{#paper-button iconButton=true}}{{paper-icon "share" size="18"}}{{/paper-button}}
        {{#paper-button iconButton=true}}{{paper-icon "shopping_basket" size="18"}}{{/paper-button}}

    {{/card.actions}}
{{/paper-card}}
</div>

component.js is as below import Ember from 'ember';

export default Ember.Component.extend({
    actions:{
      click(feed){
        console.log("Click event fired:"+feed.id); //Output is correct in console
        this.sendAction("onClick", feed); //sending onClick Action
      }
    }
});

I'm populating list of this component in one of my route. Template is as below

{{#app-sidenav user=model}}{{/app-sidenav}}
<div class="content">
  <div class="row">
      {{#each model as |item|}}
        {{#app-feed-small onClick=(action "getDetail" item) class="col-xs-5" feed=item}} {{/app-feed-small}}
      {{/each}}
   </div>
 </div>

route.js is as below import Ember from 'ember';

export default Ember.Route.extend({
    store: Ember.inject.service(),

    model(){
        //Populating module. Works just fine
    } ,
    actions:{
      getDetails(feed){
        console.log("Getting details of "+feed.id);
      }
    }   
});

I have defined getDetails action as mentioned in my template.js of the route still i am getting below error

""Assertion Failed: An action named 'getDetail' was not found in (generated feed.index controller)""

feed.index is my route.

I used same method and modified paper-chip's source to get action corresponding to click on paper-chip's item which worked. But i am not able to do same in my own component. Please let me know what is missing

3
Actions should be in controllers. If the corresponding controller bubbles up the action then the action in route called - Ebrahim Pasbani
I am using ember 2.11.0, i guess controller is deprecated in favor of component. Please Correct me if i am wrong. - Kumar Gaurav
No it's not deprecated. If you are using components so the actions should be there. But you want to handle the actions in (route). So you need controller. - Ebrahim Pasbani

3 Answers

0
votes

Your problem is that in your second last code snippet, the one with your template. You refer to the action as getDetail but in route.js your last code snippet you declare the action as getDetails which is different to the code in your template. It's a common spelling error, one has an "s" st the end whereas the other doesn't.

0
votes

The actions should be in controllers. And if controller bubbles up then the action in route be called.

For your case you don't need controller.

You can use ember-transition-helper

I assume you have in router.js :

this.route('feeds', function(){
  this.route('edit', {path: '/:id'});
});

Now your template is going to be :

{#app-sidenav user=model}}{{/app-sidenav}}
<div class="content">
  <div class="row">
      {{#each model as |item|}}
        {{#app-feed-small onClick=(transition-to "feeds.edit" item) class="col-xs-5" feed=item}} {{/app-feed-small}}
      {{/each}}
   </div>
 </div>
0
votes

sendAction is an ancient way to calling action inside controller/route.

The new style is to use closure action, which passes action as a value by creating a closure at the time of value passing.

Yes, you are correct. The action has been sendAction is able to bubble up from,

correspond controller -> correspond route -> upper route -> ... -> application route

However, closure action does NOT bubble.

Please refer to Ember component send action to route where @kumkanillam detailed explained how to call action inside route using different method and the differences between sendAction and closure action.

I have also made a sample project and write a simple explanation for it at,

https://github.com/li-xinyang/FE_Ember_Closure_Action