【问题标题】:binding context to action in ember textfield将上下文绑定到 ember 文本字段中的操作
【发布时间】:2013-02-06 20:47:51
【问题描述】:

我有一个需要管理多个聊天窗口的 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 传递给文本字段操作函数? (或者你能建议一种不同的方法来解决这个问题吗?)

【问题讨论】:

  • 你能用你的问题样本制作一个 jsFiddle 吗?玩起来真的很有帮助..

标签: ember.js handlebars.js


【解决方案1】:

在视图定义中添加contentBinding="this",如:

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

编辑

Ember master 已经有了this change,但官方下载的版本仍然没有.. 所以你需要继承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

{{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 小伙伴们尽快发布下一个版本..

【讨论】:

    【解决方案2】:

    我知道这个问题已经得到解答,但我说让我添加一些信息,这些信息可能会在操作和 TextField 的情况下对某人有所帮助。一个词“组件”。 Ember 中的TextFieldComponent,因此如果您从这个角度考虑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"}}
    

    希望这些信息能帮助某人,如果他们想知道为什么我的操作没有从这个 textField 发送。

    这个 jsBin 是一个用于组件/视图发送动作等的沙盒。没什么太花哨的,但它可能对某人有所帮助..

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

    和平,我离开这个......

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多