简体   繁体   English

Ember 3计算的属性获取器设置器

[英]Ember 3 computed property getter setter

With Ember v3.x, did something change with respect to setting a value for computed property ? 使用Ember v3.x,在为计算属性设置值方面是否有所改变? In my class, I have a CP named "cp1" 在我的课堂上,我有一个名为“ cp1”的CP

Earlier with Ember 2.x, I used to do 在Ember 2.x之前,我曾经做过

this.cp1 = cp1

But with Ember 3.x, the above is not working. 但是,使用Ember 3.x时,以上操作无效。 Do I need to update the way CP is set with Ember 3.x ? 我是否需要更新Ember 3.x设置CP的方式?

Looking at your question I can see two issues right away, the first one being about a missing this.set() and the second being that you will need to explicitly define a setter for this to work the way that you would like. 查看您的问题,我会立即看到两个问题,第一个是有关缺少this.set() ,第二个是您需要显式定义一个setter以便按您希望的方式工作。 I'll go into more details below. 我将在下面详细介绍。

As for your question about this changing between Ember 2.x and Ember 3.x I don't recall any changes that would change this behaviour 🤔 but @Lux is 100% right in their comment to you, this has never been supported behaviour so you might have been doing something that accidentally worked 😂 至于您关于在Ember 2.x和Ember 3.x之间进行此更改的问题,我不记得有任何更改可以更改此行为changes,但是@Lux在他们对您的评论中100%正确,这种行为从未得到支持,因此您可能曾经做过一些意外的事😂

So firstly let's talk about using this.set() . 因此,首先让我们谈谈使用this.set() Ember has an Object Model that requires that you use this.set() to update properties so that other parts of the system (like templates or computed properties) can be notified of the changes. Ember有一个对象模型,要求您使用this.set()更新属性,以便可以将更改通知系统的其他部分(例如模板或计算的属性)。 You can read more about this in the official documentation for accessing object properties in Ember . 您可以在Ember官方文档中了解有关此对象的更多信息。

The second thing that is important to mention is that it is not recommended to override computed properties that don't have setters defined. 值得一提的第二件事是,不建议覆盖未定义setter的计算属性。 This has been enough of an issue for new developers that setting computed properties without getters is officially deprecated since Ember 3.8 which means in the next major version of Ember (Ember 4.0) the default behaviour will change. 对于新开发人员而言,这已经是一个足够大的问题, 因为从Ember 3.8开始正式弃用没有getter的计算属性设置 ,这意味着在Ember的下一个主要版本(Ember 4.0)中,默认行为将发生变化。

If you would like to set a computed property you can read the documentation for defining a setter in Ember but I will also give you an example below. 如果您想设置计算属性,则可以阅读Ember中定义setter文档,但我还将在下面提供示例。

Assuming you have a computed property fullName() that combines firstName and lastName 假设您具有将firstNamelastName组合在一起的计算属性fullName()

fullName: computed('firstName', 'lastName', function() {
  return `${this.firstName} ${this.lastName}`;
}),

if you were to set this computed property (in an action for example) 如果要设置此计算属性(例如,在操作中)

this.set('fullName', 'Chris Manson');

then you would be overriding the behaviour of the computed property and it would stop updating if you changed firstName or lastName . 那么您将覆盖计算属性的行为,并且如果更改firstNamelastName ,它将停止更新。

If you wanted to implement some business logic that actually split the string Chris Manson and set Chris as the firstName and Manson as the lastName then you would update your computed property to be like this: 如果您想实现一些实际上拆分字符串Chris Manson并将Chris设置为firstName并将MansonlastName业务逻辑,那么您将更新计算所得的属性,如下所示:

fullName: computed('firstName', 'lastName', {
  get() {
    return `${this.firstName} ${this.lastName}`;
  },
  set(propertyName, newValue) {
    // propertyName is not used - if you logged it then it would say `fullName`
    let pieces = newValue.split(' ');

    this.set('firstName', pieces[0]);
    this.set('lastName', pieces[1]);

    return newValue;
  }
}),

This allows you to update the computed property without removing the "computed" nature of it 🎉 这使您可以在不删除计算属性的情况下更新计算属性property


This question was answered as part of "May I Ask a Question" Season 2 Episode 1. If you would like to see us discuss this answer in full and work through some example code you can check out the video here: https://youtu.be/v1rBL5_KPqU 作为“我可以问一个问题”第2季第1集的一部分,回答了这个问题。如果您希望我们全面讨论该答案并通过一些示例代码进行工作,您可以在此处查看视频: https:// youtu .be / v1rBL5_KPqU

You should use defineProperty if you need to define computed properties dynamically: 如果需要动态定义计算属性,则应使用defineProperty

import { defineProperty, computed } from '@ember/object';

export default Component.extend({
  init() {
    defineProperty(this, 'myComputedProperty', computed('someDependentKey', function() {
      return null;
    });
  }
});

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

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