我有一个需要管理多个聊天窗口的ember应用程序。在{{#each}}循环中创建每个活动聊天的窗口。这很简单。我遇到问题的地方是当用户按下回车时发送聊天消息。
窗口看起来像这样
{{#each chats}}
... stuff to display already existing chats...
{{view Ember.TextField valueBinding="text" action="sendChat"}}
<button {{action sendChat this}}> Send </button>
{{/each}}
这适用于按钮,因为我可以将this
传递给它。默认情况下,textfield视图操作中定义的函数只获取该文本字段中的文本,在这种情况下这是不够的。由于可以打开多个聊天窗口,我需要知道输入消息的窗口。是否可以将this
传递给文本字段操作函数? (或者你可以建议一种不同的方法来解决这个问题吗?)
答案 0 :(得分:3)
将 contentBinding="this"
添加到视图的定义中,例如:
{{view Ember.TextField valueBinding="text" action=sendChat contentBinding="this"}}
击> <击> 撞击>
Ember master已经有this change,但官方可下载的文字仍然没有..所以你需要继承Ember.TextField
并更改其insertNewline
以实现所需的功能:< / p>
App.ActionTextField = Em.TextField.extend({
insertNewline: function(event) {
var controller = this.get('controller'),
action = this.get('action');
if (action) {
controller.send(action, this.get('value'), this);
if (!this.get('bubbles')) {
event.stopPropagation();
}
}
}
});
之后,操作处理程序将接收其他参数 view :
{{view App.ActionTextField valueBinding="text" action=sendChat myfieldBinding="this"}}
并在控制器中:
sendChat: function (text, view) {
var myField = view.get('myfield');
//do stuff with my field
}
您可以使用ember master而不是子类化Ember.TextField
..
我希望这些蠢货家很快就会发布下一个版本..
答案 1 :(得分:2)
我知道这个问题已得到解答,但我说让我添加一些可能有助于行动和TextField情况的人的信息。一个词“Component”。 Ember中的TextField
是Component
所以如果从这个角度考虑TextField
,那么在应用程序中发送动作和使用TextField时可能会有所帮助。
所以当你说App.SomeTextField = Ember.TexField.extend({...});
App.SomeTextField正在继承Ember.TextField(记住哪个是组件)。你可以在里面添加你的逻辑,它可以工作,你可以从模板中访问它,例如{{view App.SomeTextField}}
你可能会认为我看到这个人很糟糕的'观点'这个词,TextField
是一个观点。嗯,它有点像View,因为Ember Components是Ember.View的子类,所以它们拥有所有的Views。但是有一些重要的事情要记住组件un-like Views不会吸收它们周围的上下文(信息/数据),它们会锁定所有内容,如果你想从外部环境中发送一些内容,你必须明确地这样做。 / p>
因此,要在模板中将内容传递到App.SomeTextField
,您可以执行类似{{view App.SomeTextField value=foo action="sendChat"}}
的操作,其中传递两个值,并在此情况下执行操作。您可以稍微在View / Component之间骑行,但事情会崩溃为什么你的行动不发送?
现在这是事情变得有点冒险的地方。请记住,TextField
是一个Component,它是View的子类,但View不是Component。由于组件是您尝试执行this.get('controller').send('someAction', someParam)
时自己的封装元素,因此“this”指的是Component本身,而控制器再次成为其自身关于此代码的组件。您希望的操作将转到外部环境,而您的应用程序则不会。
为了解决这个问题,您必须遵循从组件发送操作的协议。这就像是
App.SomeTextField = Ember.TextField.extend({
//this will fire when enter is pressed
insertNewline: function() {
//this is how you send actions from components
//we passed sendChat action in
//Your logic......then send...
this.sendAction('sendChat');
}
});
现在在与SomeTextField组件/视图元素相关联的控制器中
App.SomeController = Ember.Controller.extend({
//In actions hash capture action sent from SomeTextField component/view element
actions: {
sendChat: function() {
//Your logic well go here...
}
}
});
现在我说将TextField视为一个组件,但我一直在视图的尾部并声明{{view AppSomeTextField ...}}。让我们像组件一样。
因此,您可以在模板中使用它
//在某个模板中
`{{some-text-field}}`
然后,您将获得名称为
的组件的特定模板//与组件关联的模板
<script type="text/x-handlebars" data-template-name="components/some-text-field">
Add what you want
</script>
在你的JS中声明你的组件:
//important word 'Component' must be at end
App.SomeTextFieldComponent = Ember.TextField.extend({
//same stuff as above example
});
由于我们在角色上你可能使用Ember输入助手获得相同的功能。它们非常强大。
{{input action="sendChat" onEvent="enter"}}
Welp希望这些信息可以帮助某人,如果他们卡住了解我的动作为什么不从此textField发送。
这个jsBin是一个用于组件/视图发送动作等的沙箱....没有什么太花哨但它可以帮助某人..
和平,我离开这个......