【问题标题】:How are Ember Octane Glimmer component @actions called?Ember Octane Glimmer 组件 @actions 是如何调用的?
【发布时间】:2020-03-31 04:23:02
【问题描述】:

此问题与Ember Octane Upgrade How to pass values from component to controller有关

我一直在努力从 HBS 表单接收值并将其分配到组件中,然后将其传递给控制器​​。工作答案表明我必须为每个表单字段创建一个@action 函数。例如:

@action
changeNewPassword(ev) {
    this.newPassword = ev.target.value;
}

但是,我不明白这些函数在哪里或如何被调用,所以我不明白它们为什么起作用。有谁知道这些函数是怎么调用的?

模板组件 HBS

<div class="middle-box text-center loginscreen animated fadeInDown">
    <div>
        <h3>Change Password</h3>
        <form class="m-t" role="form" {{on "submit" this.changePassword}}>
            {{#each this.errors as |error|}}
                <div class="error-alert">{{error.detail}}</div>
            {{/each}}
            <div class="form-group">
                <Input @type="password" class="form-control" placeholder="Old Password" @value={{this.oldPassword}} required="true" />
            </div>
            <div class="form-group">
                <Input @type="password" class="form-control" placeholder="New Password" @value={{this.newPassword}} required="true" />
            </div>
            <div class="form-group">
                <Input @type="password" class="form-control" placeholder="Confirm Password" @value={{this.confirmPassword}} required="true" />
            </div>
            <div>
                <button type="submit" class="btn btn-primary block full-width m-b">Submit</button>
            </div>
        </form>
    </div>
</div>

模板 HBS

<Clients::ChangePasswordForm @chgpwd={{this.model}} @changePassword={{action 'changePassword'}} @errors={{this.errors}} />

模板组件 JS

import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { action } from '@ember/object';

export default class ChangePasswordForm extends Component {

    @tracked oldPassword;
    @tracked newPassword;
    @tracked confirmPassword;
    @tracked errors = [];

    @action
    changeOldPassword(ev) {
        this.oldPassword = ev.target.value;
    }
    @action
    changeNewPassword(ev) {
        this.newPassword = ev.target.value;
    }
    @action
    changeConfirmPassword(ev) {
        this.confirmPassword = ev.target.value;
    }

    @action
    changePassword(ev) {

        ev.preventDefault();

        this.args.changePassword({
            oldPassword: this.oldPassword,
            newPassword: this.newPassword,
            confirmPassword: this.confirmPassword
        });
    }
}

【问题讨论】:

  • 看来你有很多后续问题。你考虑过加入 Ember Discord 吗?

标签: ember.js


【解决方案1】:

在 Ember Octane 中,您希望使用 on 修饰符来设置操作。

线

<form class="m-t" role="form" {{on "submit" this.changePassword}}>

有效地为此表单元素的submit 事件设置了一个事件监听器,它将调用组件类上的changePassword 函数(因为this.changePassword 中的this 意味着该函数是组件本地的)

调用此操作:

@action
changePassword(ev) {

  ev.preventDefault();

  this.args.changePassword({
    oldPassword: this.oldPassword,
    newPassword: this.newPassword,
    confirmPassword: this.confirmPassword
  });
}

这个changePassword 操作依次调用changePassword 函数,该函数在命名参数@changePassword 下传递给组件

<Clients::ChangePasswordForm @chgpwd={{this.model}} @changePassword={{action 'changePassword'}} @errors={{this.errors}} />

现在,在您的 Template Component JS 中,您还有其他三个操作

  1. changeOldPassword
  2. changeNewPassword
  3. changeConfirmPassword

据我从您发布的代码中可以看出,从未使用过。它们看起来像用于设置单向绑定输入的代码,但您使用的是内置 Input,即 Ember input built-in component(并在输入值和 @987654338 之间使用双向绑定@)。需要注意的非常重要的区别是Input 上的大写I。所有尖括号组件都使用标题大小写(每个单独的单词都以大写字母开头)。

你有没有做过类似的事情:

<input type="password" class="form-control" placeholder="New Password" value={{this.newPassword}} {{on 'input' this.changeNewPassword}} required="true">

然后您将this.changeNewPassword 函数绑定到&lt;input&gt; 元素的input 事件(这是本机html &lt;input&gt;。使用您定义的changeNewPassword 操作:

@action
changeNewPassword(ev) {
  this.newPassword = ev.target.value;
}

您可以通过单向绑定使this.newPassword 值与输入保持同步。

【讨论】:

    【解决方案2】:

    我看到您在示例中使用动作的方式有两种。

    1. 通过{{on}}:
    <form class="m-t" role="form" {{on "submit" this.changePassword}}>
    

    这种情况更简单。当您在组件模板中执行this 时,您指的是组件的类,因此当form 元素中发生提交DOM 事件时,模板会调用this.changePassword

    您可以在{{on}} API docs查看更多信息。

    1. 通过{{action}}
    <Clients::ChangePasswordForm @chgpwd={{this.model}} @changePassword={{action 'changePassword'}} @errors={{this.errors}} />
    

    在这种情况下,只要在Clients::ChangePasswordForm 内触发@changePassword,Ember 就会在组件类中的操作哈希(经典语法)或装饰方法(@action)中搜索changePassword即使用Clients::ChangePasswordForm

    您可以在{{action}} API docs查看更多信息。

    希望这有助于阐明作用机制。

    如需额外作业,您可能需要查看upgrade guides on actions

    【讨论】:

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