2

我有一个需要管理多个聊天窗口的 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给它。默认情况下,在文本字段视图操作中定义的函数只获取该文本字段中的文本,在这种情况下这还不够。由于可以打开多个聊天窗口,我需要知道消息输入到哪个窗口。是否可以传递this给文本字段操作函数?(或者你能建议一种不同的方法来解决这个问题吗?)

4

2 回答 2

3

添加contentBinding="this"到视图的定义中,例如:

{{view Ember.TextField valueBinding="text" action=sendChat contentBinding="this"}}

编辑

Ember master 已经有了这个改变,但是官方下载的版本仍然没有.. 所以你需要子类化Ember.TextField并改变它insertNewline来实现所需的功能:

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

希望ember大佬快点发布下一个版本。。

于 2013-02-06T21:04:31.423 回答
2

我知道这个问题已经得到解答,但我说让我添加一些信息,这些信息可能会在操作和 TextField 的情况下对某人有所帮助。一个词“组件”TextField在 Ember 中Component,如果您TextField从这个角度考虑,它在发送操作和在应用程序中使用 TextField 时可能会有所帮助。

所以当你说App.SomeTextField = Ember.TexField.extend({...});App.SomeTextField 是 Ember.TextField 的子类时(记住它是一个组件)。你可以在里面添加你的逻辑并且可以工作,你可以从你的模板访问它,例如 {{view App.SomeTextField}}

你可能会想我看到这个家伙很烂的“观点”这个词,TextField是一个观点。嗯,它是一种视图,因为 Ember 组件是 Ember.View 的子类,因此它们具有视图所具有的所有功能。但是有一些重要的事情要记住,与视图不同的组件不会吸收它们周围的上下文(信息/数据),它们会锁定所有内容,如果你想从外部周围的上下文中发送一些东西,你必须明确地这样做。

因此,要将事物传递到App.SomeTextField您拥有它的模板中,您将执行类似{{view App.SomeTextField value=foo action="sendChat"}}传递两个事物值和在这种情况下的操作的地方。您可能可以在视图/组件之间稍作调整,但事情会崩溃,为什么您的操作没有发送?

现在这是事情变得有点迷幻的地方。记住TextField是一个组件,它是视图的子类,但视图不是组件。由于组件是它们自己封装的元素,当您尝试执行此操作时this.get('controller').send('someAction', someParam),“this”指的是组件它的自身,而控制器在此代码方面再次是组件的自身。您希望的操作将转到外部环境,而您的应用程序不会。

为了解决这个问题,您必须遵循从组件发送操作的协议。会是这样的

 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 是一个用于组件/视图发送动作等的沙盒......没什么太花哨的,但它可能对某人有帮助..

http://emberjs.jsbin.com/suwaqobo/3/

和平,我离开这个...

于 2014-03-15T01:36:18.267 回答