[英]Ember component sendAction() not working
i have been struggling with this for the past few hours, i am making an ember application for creating an invoice.在过去的几个小时里,我一直在努力解决这个问题,我正在制作一个用于创建发票的 ember 应用程序。 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.
我正在使用 ember 组件(文本字段)来使用键盘修改字段,但是由于操作没有发送回相关控制器,我无法将记录保存在 focusOut 或 insertNewLine 上,并且什么也没有发生。 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这应该是这样的: 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...在组件上调用 console.log 函数,sendAction 调用从不工作......
Thanks for the help.感谢您的帮助。
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');
}
});
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')
});
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>
<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);
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}}
As an addition to the nice answer by @Kingpin2k you can also define your action's name within the component if it is always the same and you want to simplify the syntax of including your component.作为@Kingpin2k 的不错答案的补充,如果它始终相同并且您想简化包含组件的语法,您还可以在组件中定义您的操作名称。 ie.
即。
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'),
});
In this example the component uses the parent controllers transitionToRoute method to change routes, even though the component may not be a button/link.在这个例子中,组件使用父控制器的 transitionToRoute 方法来改变路由,即使组件可能不是按钮/链接。 For example, navigating on change of a component containing several select inputs, or just changing route from within a component in general.
例如,导航包含多个选择输入的组件的更改,或者通常只是更改组件内的路由。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.