从 ember 组件获取 ember 组件的属性-class

Getting properties of ember component from ember component-class

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

new.hbs

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

在“AuctionForm”组件内的 select 标签上使用 selected 产品,如下所示:

拍卖-form.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>

我想将这两个对象绑定到 class 的“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()”函数访问它在组件-class 上的值时(就像我在以前的 ember 版本中所做的那样)我收到一条错误消息,指出“this.get 不是一个函数”。

在网上搜索了很多之后,我找不到直接的解决方案,也没有找到文档提供的官方解决方案。

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

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 中执行此类任务的正确方法吗?

非常感谢。

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

  1. 必须通过 js class 中的 args property 访问参数,例如 this.args.auction.

  2. 参数(auctionproducts)在组件内部不可变。要更改参数的值,我们可以 send an action to the parent 更改值。

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

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

  5. 绑定事件,推荐使用on modifier and fn helper

通过合并所有点,

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 migration cheat sheet 在从 classic ember 迁移代码库时会很方便模型到 Octane 模型。