简体   繁体   English

Ember Octane Glimmer 组件@actions 是如何调用的?

[英]How are Ember Octane Glimmer component @actions called?

This question is related to Ember Octane Upgrade How to pass values from component to controller这个问题与Ember Octane Upgrade How to pass values from component to controller 有关

I was struggling to receive and assign values from an HBS form into a component and then pass it to the controller.我正在努力从 HBS 表单接收值并将其分配到组件中,然后将其传递给控制器​​。 The working answer showed that I had to create an @action function for each form field.工作答案表明我必须为每个表单字段创建一个@action函数。 For example:例如:

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

But, I do not understand where or how those functions are called and so I do not understand why they work.但是,我不明白在何处或如何调用这些函数,因此我不明白它们为什么起作用。 Does anyone know how these functions are called?有谁知道这些函数是如何调用的?

Template Component HBS模板组件 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>

Template HBS模板 HBS

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

Template Component JS模板组件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
        });
    }
}

In Ember Octane, you want to use the on modifier for setting up actions.在 Ember Octane 中,您希望使用on修饰符来设置操作。

The line线

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

effectively sets up an event listener for the submit event of this form element which will invoke the changePassword function on the component's class (because the this in this.changePassword means that the function is local to the component)有效地为这个表单元素的submit事件设置一个事件监听器,它将调用组件类上的changePassword函数(因为this.changePasswordthis意味着该函数是组件本地的)

That invokes this action:调用此操作:

@action
changePassword(ev) {

  ev.preventDefault();

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

This changePassword action is in turn invoking the changePassword function that was passed to the component under the named argument @changePasswordchangePassword操作依次调用在命名参数@changePassword下传递给组件的changePassword函数

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

Now, in your Template Component JS you have three other actions现在,在您的Template Component JS您还有其他三个操作

  1. changeOldPassword
  2. changeNewPassword
  3. changeConfirmPassword

which, as far as I can tell from the code you posted, are never used.据我从您发布的代码中可以看出,从未使用过。 They look like code you would use to set up a 1-way bound input, but you are using the built-in Input which is the Ember input built-in component (and uses two-way binding between the input value and the @value ).它们看起来像用于设置单向绑定输入的代码,但您使用的是内置Input ,它是 Ember 输入内置组件(并在输入值和@value之间使用双向绑定)。 The very important distinction to note is the capital I on Input .需要注意的非常重要的区别是Input上的大写I All angle bracket components use title-casing (each separate word starts with a capital letter).所有尖括号组件都使用标题框(每个单独的单词都以大写字母开头)。

Had you instead done something like:如果您改为执行以下操作:

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

Then you would have bound the this.changeNewPassword function to the input event of the <input> element (which is the native html <input> . With the changeNewPassword action as you've defined:然后,您将this.changeNewPassword函数绑定到<input>元素的input事件(这是本机 html <input> 。使用您定义的changeNewPassword操作:

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

You would have kept the this.newPassword value in sync with the input via one way binding.您可以通过一种方式绑定使this.newPassword值与输入保持同步。

There are two ways I see you are using actions in your examples.我看到您在示例中使用操作的方式有两种。

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

This case is more straightforward.这个案例更直接。 When you do this in a component template, you are referring to the component's class, so, this.changePassword is called by the template when the submit DOM event happens in the form element.当您在组件模板中执行this时,您指的是组件的类,因此,当提交 DOM 事件在form元素中发生时,模板会调用this.changePassword

You can see more information in the {{on}} API docs .您可以在{{on}} API 文档 中查看更多信息。

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

In this case, whenever @changePassword is triggered inside Clients::ChangePasswordForm , Ember will search for a changePassword either in the actions hash (classic syntax) or a decorated method ( @action ) in the class of the component that is using Clients::ChangePasswordForm .在这种情况下,每当@changePasswordClients::ChangePasswordForm被触发时,Ember 将在使用Clients::ChangePasswordForm的组件的类中的操作哈希(经典语法)或修饰方法( @action )中搜索changePasswordClients::ChangePasswordForm

You can see more information in the {{action}} API docs .您可以在{{action}} API 文档 中查看更多信息。

Hope this helps clarify the action mechanisms.希望这有助于阐明作用机制。

For extra homework, you might want to check the upgrade guides on actions .对于额外的作业,您可能需要查看有关操作升级指南

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM