1

问题

我经常使用这种计算属性,其中 setter 只返回新值:

  @computed('args.myValue')
  get myValue() {
    return this.args.myValue;
  }
  set myValue(newValue) {
    return newValue; // <==== this is no longer valid with native setter
  }

这做了几件事:

  1. 将初始值设置为args.myValue
  2. 允许更改值(通常通过<Input @value={{this.myValue}} />
  3. args.myValue更改时恢复默认值

return问题来自没有任何价值的本地设置器。

请注意,我可能会找到一个“hackish”解决方案,但我希望拥有遵循新 EmberJS 约定的代码,以避免以后痛苦的更新。

我尝试过的事情

手动缓存

  @tracked _myValue = null;

  get myValue() {
    return this._myValue || this.args.myValue;
  }
  set myValue(newValue) {
    this._myValue = newValue;
  }

这不起作用,因为_myValue总是在第一个之后设置myValue=(newValue)。为了使其工作,应该有某种观察者将其重置为null更改args.myValue

可悲的是,观察者不再是带有原生类的 EmberJS 的一部分

{{unbound}}帮手

<Input @value={{unbound this.myValue}} />

正如预期的那样,它不起作用,因为它只是不更新myValue​​。

{{unbound}}帮手结合event.target.value搬运

<Input @value={{unbound this.myValue}} {{on "keyup" this.keyPressed}} />
  get myValue() {
    return this.args.myValue;
  }

  @action keyPressed(event) {
    this.doStuffThatWillUpdateAtSomeTimeMyValue(event.target.value);
  }

但是更改Input时仍然没有更新args.myValue

初始代码

这是一个更具体的使用示例:

零件

// app/components/my-component.js

export default class MyComponent extends Component {

  @computed('args.projectName')
  get projectName() {
    return this.args.projectName;
  }
  set projectName(newValue) {
    return newValue; // <==== this is no longer valid with native setter
  }

  @action
  searchProjects() {
    /* event key stuff omitted */
    const query = this.projectName;
    this.args.queryProjects(query);
  }
}
{{! app/components/my-component.hbs }}

<Input @value={{this.projectName}} {{on "keyup" this.searchProjects}} />

控制器

// app/controllers/index.js

export default class IndexController extends Controller {

  get entry() {
    return this.model.entry;
  }

  get entryProjectName() {
    return this.entry.get('project.name');
  }

  @tracked queriedProjects = null;

  @action queryProjects(query) {
    this.store.query('project', { filter: { query: query } })
      .then((projects) => this.queriedProjects = projects);
  }

  @action setEntryProject(project) {
    this.entry.project = project;
  }
}
{{! app/templates/index.hbs }}

<MyComponent 
  @projectName={{this.entryProjectName}} 
  @searchProjects={{this.queryProjects}} />

queriedProjects控制器中设置 时,组件将显示它们。

当单击这些搜索结果之一时,控制器会更新setEntryProject被调用的。

4

1 回答 1

0

根据这个 Ember.js 讨论

Net,我自己的观点是,正是出于这个原因,使用常规<input>而不是<Input>组件通常更好,并连接您自己的事件侦听器。这将使您负责在操作中设置 item.quantity 值,但它也消除了最后一个问题,即使用两种不同的方式设置相同的值,它还让您有机会通过事件处理来做其他事情。

我通过使用标准找到了解决此问题的方法<input>,这似乎是解决它的“正确方法”(我将非常感谢任何告诉我更好方法的评论):

{{! app/components/my-component.hbs }}

<input value={{this.projectName}} {{on "keyup" this.searchProjects}} />
// app/components/my-component.js

@action
searchProjects(event) {
  /* event key stuff omitted */
  const query = event.target.value;
  this.args.queryProjects(query);
}

如果我需要将输入值保留为属性,我可以这样做:

{{! app/components/my-component.hbs }}

<input value={{this.projectName}} 
  {{on "input" this.setProjectQuery}} 
  {{on "keyup" this.searchProjects}} />
// app/components/my-component.js

@action setProjectQuery(event) {
  this._projectQuery = event.target.value;
}

@action
searchProjects( {
  /* event key stuff omitted */
  const query = this._projectQuery;
  this.args.queryProjects(query);
}
于 2022-02-26T16:05:28.250 回答