本文介绍了Ember Octane 升级如何将值从组件传递到控制器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从 Ember 升级到 >=3.15.如何将表单值从控制器传递到组件?

我无法解释尝试的诊断组合的数量及其收到的相应错误.所以,我想最好问问它应该如何正确完成?是否涉及 Glimmer?

一个简单的例子:将更改密码 from old 密码 to 传递给 new通过组件向控制器确认密码.在 Component 中,我不断收到 onsubmit() is not a function 错误.

代码示例:

用户输入表单

ChangePasswordForm.hbs

<div><h3>更改密码</h3><form class="m-t" role="form" {{on "submit" this.changePassword}}>{{#each 错误为 |error|}}<div class="error-alert">{{error.detail}}</div>{{/每个}}<div class="form-group">{{input type="password" class="form-control" placeholder="旧密码" value=oldPassword required="true"}}

<div class="form-group">{{input type="password" class="form-control" placeholder="新密码" value=newPassword required="true"}}

<div class="form-group">{{input type="password" class="form-control" placeholder="Confirm Password" value=confirmPassword required="true"}}

<div><button type="submit" class="btn btn-primary block full-width m-b">Submit</button>

</表单>

模板组件

ChangePassword.hbs

<Clients::ChangePasswordForm @chgpwd={{this.model}} {{on "submit" this.changePassword}} @errors={{this.errors}}/>

组件

ChangePasswordForm.js

从'@glimmer/component'导入组件;从@glimmer/tracking"导入{跟踪};从'@ember/object'导入{动作};导出默认类 ChangePasswordForm 扩展组件 {@tracked oldPassword;@tracked newPassword;@tracked 确认密码;@tracked 错误 = [];@行动更改密码(ev){//阻止表单的默认操作.ev.preventDefault();this.oldPassword = ev.oldPassword;this.newPassword = ev.newPassword;this.confirmPassword = ev.confirmPassword;//调用表单的 onsubmit 方法并传入组件的值.this.onsubmit({旧密码:this.oldPassword,新密码:this.newPassword,确认密码:this.confirmPassword});}}

控制器

ChangePassword.js

从'@ember/controller'导入控制器;从@ember/service"导入{注入为服务};从'@ember/object'导入{动作};导出默认类 ChangePassword 扩展控制器 {@服务阿贾克斯@服务会话@行动更改密码(属性){if(attrs.newPassword == attrs.oldPassword){this.set('错误', [{detail: "旧密码和新密码是一样的,密码没变.",状态:1003,标题:'更改密码失败'}]);}否则 if(attrs.newPassword != attrs.confirmPassword){this.set('错误', [{详细信息:新密码和确认密码必须是相同的值.密码没有改变.",状态:1003,标题:'更改密码失败'}]);}别的{let token = this.get('session.data.authenticated.token');this.ajax.request(this.store.adapterFor('application').get('host') + "/clients/change-password", {方法:'POST',数据:JSON.stringify({数据: {属性: {旧密码":attrs.oldPassword,新密码":attrs.newPassword,确认密码":attrs.confirmPassword},类型:'更改密码'}}),标题:{'授权':`Bearer ${token}`,'内容类型':'应用程序/vnd.api+json','接受':'应用程序/vnd.api+json'}}).then(() => {//转换到更改密码成功路线.this.transitionToRoute('clients.change-password-success');}).catch((ex) => {//将错误属性设置为 ex.payload.errors 中保存的错误.这将允许在 UI 中显示错误.this.set('errors', ex.payload.errors);});}}}

型号

ChangePassword.js

从'@ember/routing/route'导入路由;从'../../mixins/abc-authenticated-route-mixin'导入AbcAuthenticatedRouteMixin;导出默认 Route.extend(AbcAuthenticatedRouteMixin, {//导出默认类ChangePasswordRoute extends Route(AbcAuthenticatedRouteMixin, {模型() {返回 {旧密码: '',新密码: '',确认密码: ''};},})
解决方案

@glimmer/component中没有onsubmit方法,所以不能调用this.onsubmit 在组件中的操作中.

首先,您需要将在控制器中创建的操作传递给您的组件.可以这样做:

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

记住,你不能再在一个 glimmer 组件中传递数据,你需要使用一个动作,因为一切都是一种方式绑定.

其次,你需要在你的 glimmer 组件中调用这个动作:

this.args.changePassword({旧密码:this.oldPassword,新密码:this.newPassword,确认密码:this.confirmPassword});

我创建了一个 Ember Twiddle 来展示这个例子的工作.

Upgrade from Ember <3.15 to >=3.15. How do I pass form values from a controller into a component?

I cannot begin to explain the number of diagnostic combinations attempted and their corresponding errors received. So, I figure it best to ask how it should be done correctly? Is Glimmer involved?

A simple example: pass a change password from old password to both a new and confirm password via a component to a controller. In the Component, I keep getting onsubmit() is not a function error.

Code example:

User Input Form

ChangePasswordForm.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 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=oldPassword required="true"}}
            </div>
            <div class="form-group">
                {{input type="password" class="form-control" placeholder="New Password" value=newPassword required="true"}}
            </div>
            <div class="form-group">
                {{input type="password" class="form-control" placeholder="Confirm Password" value=confirmPassword required="true"}}
            </div>
            <div>
                <button type="submit" class="btn btn-primary block full-width m-b">Submit</button>
            </div>
        </form>
    </div>
</div>

Template Component

ChangePassword.hbs

<Clients::ChangePasswordForm @chgpwd={{this.model}} {{on "submit" this.changePassword}} @errors={{this.errors}} />

Component

ChangePasswordForm.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
    changePassword(ev) {

        // Prevent the form's default action.
        ev.preventDefault();

        this.oldPassword = ev.oldPassword;
        this.newPassword = ev.newPassword;
        this.confirmPassword = ev.confirmPassword;

        // Call the form's onsubmit method and pass in the component's values.

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

Controller

ChangePassword.js

import Controller from '@ember/controller';
import { inject as service } from '@ember/service';
import { action } from '@ember/object';

export default class ChangePassword extends Controller {

    @service ajax 
    @service session

    @action
    changePassword(attrs) { 

        if(attrs.newPassword == attrs.oldPassword)
        {
            this.set('errors', [{
                detail: "The old password and new password are the same.  The password was not changed.",
                status: 1003,
                title: 'Change Password Failed'
            }]);
        }
        else if(attrs.newPassword != attrs.confirmPassword)
        {
            this.set('errors', [{
                detail: "The new password and confirm password must be the same value.  The password was not changed.",
                status: 1003,
                title: 'Change Password Failed'
            }]);
        }
        else
        {
            let token = this.get('session.data.authenticated.token');

            this.ajax.request(this.store.adapterFor('application').get('host') + "/clients/change-password", {
                method: 'POST',
                data: JSON.stringify({ 
                    data: {
                        attributes: {
                            "old-password" : attrs.oldPassword,
                            "new-password" : attrs.newPassword,
                            "confirm-password" : attrs.confirmPassword
                        },
                        type: 'change-passwords'
                    }
                }),
                headers: {
                    'Authorization': `Bearer ${token}`,
                    'Content-Type': 'application/vnd.api+json',
                    'Accept': 'application/vnd.api+json'
                }
            })
            .then(() => {

                // Transistion to the change-password-success route.
                this.transitionToRoute('clients.change-password-success');
            })
            .catch((ex) => {

                // Set the errors property to the errors held in the ex.payload.errors.  This will allow the errors to be shown in the UI.
                this.set('errors', ex.payload.errors);
            });
        }
    }
}

Model

ChangePassword.js

import Route from '@ember/routing/route';
import AbcAuthenticatedRouteMixin from '../../mixins/abc-authenticated-route-mixin';

export default Route.extend(AbcAuthenticatedRouteMixin, {
//export default class ChangePasswordRoute extends Route(AbcAuthenticatedRouteMixin, {

    model() {

        return {
            oldPassword: '',
            newPassword: '',
            confirmPassword: ''
        };
    },
})
解决方案

There is no onsubmit method in @glimmer/component, so you cannot call this.onsubmit inside an action in the component.

First, you need to pass the action created in your controller to your component. This can be done like this:

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

Remember, you cannot pass data up any more in a glimmer component, you need to use an action since everything is one way binding.

Second, you need to call this action inside your glimmer component:

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

I've created an Ember Twiddle for you to show this example working.

这篇关于Ember Octane 升级如何将值从组件传递到控制器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-22 23:45