Ember 组件 sendAction() 不起作用 [英] Ember component sendAction() not working

查看:22
本文介绍了Ember 组件 sendAction() 不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

过去几个小时我一直在为此苦苦挣扎,我正在制作一个用于创建发票的 ember 应用程序.我正在使用 ember 组件(文本字段)来修改使用键盘的字段,但是由于操作没有发送回相关控制器,我无法将记录保存在 focusOut 或 insertNewLine 上,并且什么也没有发生.我正在使用:

Ember : 1.1.2Ember 数据:1.0.0-beta.3车把:1.0.0jQuery:1.9.1

这应该是这样的:https://dl.dropboxusercontent.com/u/7311507/embercomponent.png

问题似乎出在控制器或组件中,我似乎遗漏了一些东西.

console.log 函数在组件上被调用,sendAction 调用从不工作......

感谢您的帮助.

物品路线

App.ItemsRoute = Ember.Route.extend({渲染模板:函数(){//渲染默认插座this.render();//渲染额外的插座this.render("client", { outlet: "client", into: "application"});},模型:函数(){return this.store.find('item');}});

ItemsController

App.ItemsController = Em.ArrayController.extend({动作:{createItem: function () {//永远不会从组件中调用var title = "新元素"//创建新的 Todo 模型var item = this.store.createRecord('item', {描述:标题,数量:1,价格:0});//保存新模型item.save();}},总计数:函数(){无功总计 = 0;this.get('model').forEach(function(item){total += item.get('totalprice');});总回报;}.property('@each.qty', '@each.price')});

物品控制器

App.ItemController = Em.ObjectController.extend({didInsertElement: 函数(){this.$().focus();},动作:{testAction: function(){//永远不会从组件中调用console.log("控制器收到了 testAction 的调用");},保存项目:函数(值){this.get('model').save();},删除项目:功能(){var item = this.get('model');item.deleteRecord();item.save();},},isHovering: 假});

项目模板

ItemView 模板

视图/组件

App.ItemView = Em.View.extend({模板名称:项目",标签名称:tr",鼠标输入:函数(事件){this.get('controller').set('isHovering', true);},鼠标离开:函数(事件){this.get('controller').set('isHovering', false);}});App.EditItem = Em.TextField.extend({成为焦点:函数(){this.$().focus();}.on('didInsertElement'),插入换行符:函数(){console.log('试图插入新行');//作品this.triggerAction('createItem');//不起作用},焦点输出:函数(​​){console.log('Focused the Field Out')//WORKSthis.triggerAction('testAction', this);//不起作用}});App.EditItemNumber = App.EditItem.extend({成为焦点:空,属性绑定:["min", "max", "step"],类型:数字",分钟:0"});Ember.Handlebars.helper('edit-item', App.EditItem);Ember.Handlebars.helper('edit-item-number', App.EditItemNumber);

解决方案

在模板中定义组件时,您应该定义操作将发送到的位置.

{{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({模板名称:'some_template',动作:函数(){//等等等等}}));{{edit-item}}

i have been struggling with this for the past few hours, i am making an ember application for creating an invoice. i am using ember component (textfield) to modify the fields using the keyboard, but since actions are not sending back to the relevant controller, i cannot save the records on focusOut or insertNewLine and nothing is happening. i am using :

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

this is supposed to look like this: https://dl.dropboxusercontent.com/u/7311507/embercomponent.png

The problem seems to lie within either the controller or the component, it seems i am missing something.

the console.log function gets called on the component, the sendAction call never works...

Thanks for the help.

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
});

Items Template

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

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

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

ItemView template

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

Views / Components

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

解决方案

You should define where the action will be sent when defining a component in the template.

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

this is in case the action has a different name in different places (since this is a component, it could have different meanings in different locations). It also avoids clashing actions/triggered actions. Think of the idea of having two instances of a component, and each one should trigger a different action in the controller

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

in your case you can just write

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

And inside your component you would call

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

If you don't care about it being self contained like a component, you might want to just use a view and not a component. You can register it as a helper and it'd look just as pretty.

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

  actions: function(){
   // etc etc
  } 

})); 

{{edit-item}}

这篇关于Ember 组件 sendAction() 不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆