1

我一直在尝试从其类的操作中获取组件属性的值。我的主要目标是关联两个对象:传递给我的组件的“拍卖”(如下代码所示)

新的.hbs

<AuctionForm 
    @auction={{@model.auction}}
    @products={{@model.products}}/>

在“AuctionForm”组件内的选择标签上选择产品,如下所示:

拍卖形式.hbs

<div class="row">
    <label for="product">Produto</label>
    <select name="product" onchange={{action 'selectProduct' value='target.value'}}>
        <option value="" selected='selected' disabled='disabled'>-------</option>
        {{#each @products as |product|}}
            <option value="{{product.id}}" selected={{if (equalstr product.id @auction.product.id) 'selected'}}>{{product.name}}</option>
        {{/each}}
    </select>
</div>

我想在类的“selectProduct”动作上绑定这两个对象:

拍卖-form.js

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


export default class AuctionFormComponent extends Component {
    @action selectProduct(product) {
        this.get('auction').set('product', product); // this doesn't work on ember newest version
    }
    @action save(auction) {
        auction.save();
    }
}

虽然,每当我尝试通过“this.get()”函数访问它在组件类上的值时(就像我以前在以前的 ember 版本上所做的那样),我收到一条错误消息,指出“this.get 不是函数” .

在网上挖掘了很多之后,我找不到一个简单的解决方案,也没有文档提供的官方解决方案。

我最接近解决方案的是将“拍卖”声明为计算属性(https://api.emberjs.com/ember/3.22/classes/Component)。但是,一旦它的结构(如下面的代码)仅适用于 TypeScript 文件,我就无法在 javascript 文件上实现它。

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


export default class AuctionFormComponent extends Component {
    auction: computed('auction', function() {
        return this.auction;
    }
    @action selectProduct(product) {
        debugger;
        this.get('auction').set('product', product);
    }
    @action save(auction) {
        auction.save();
    }
}

有谁知道在 ember 3.22 中执行此类任务的正确方法?

非常感谢你。

4

1 回答 1

4

由于您使用的是现代 Glimmer 组件(从 导入@glimmer/component),

  1. 必须通过js 类中的args属性this.args.auction访问参数,例如.

  2. 参数 (auctionproducts) 在组件内部是不可变的。要更改参数的值,我们可以向父级发送操作以更改值。

  3. 和方法在微光组件getset不可用。这些方法是经典 ember 组件的一部分。您可以使用点 [.] 符号访问类的属性,例如:this.auction并使用赋值语句重新分配值,例如this.property = 'value'

  4. 由于您使用的是本机类语法,action: computed(..)因此不是有效的声明。

  5. 绑定事件,推荐使用on修饰符和fn助手

通过结合所有的点,

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

export default class AuctionFormComponent extends Component {
    @action 
    selectProduct(event) {
        // This `updateProduct` has to be implemented in parent class 
        // which mutates the `auction` object.
        this.args.updateProduct(event.target.value); // -> `on` modifier will capture the native event
    }

    @action 
    save(auction) {
        auction.save();
    }
}
<div class="row">
    <label for="product">Produto</label>
    <select name="product" {{on "change" this.selectProduct}}>
        <option value="" selected='selected' disabled='disabled'>-------</option>
        {{#each @products as |product|}}
            <option value="{{product.id}}" selected={{if (equalstr product.id @auction.product.id) 'selected'}}>{{product.name}}</option>
        {{/each}}
    </select>
</div>

调用会像,

<AuctionForm 
    @auction={{@model.auction}}
    @products={{@model.products}}
    @updateProduct={{this.updateProduct}}
/>

在这里,updateProduct需要正确实施以更新产品。


编辑:正如@BPorto 在评论中提到的,在将代码库从经典 ember 模型迁移到 Octane 模型时,这个Ember octane 迁移备忘单会很方便。

于 2020-12-02T07:41:56.790 回答