@cached는 언제 EmberJS에서 다시 계산됩니까?
11137 단어 ember
productName
이 있다고 가정해 보겠습니다. 간단하게 작업을 간단한 버튼 클릭으로 만들어 제품 이름을 항상 bar
로 업데이트합니다.// template.hbs
<button
type="button"
{{on "click" (fn this.updateProductName 'bar')}}
>
Update Product Name
</button>
<p>
Product name is: {{this.productName}}
</p>
<p>
Product details are: {{this.productDetails}}
</p>
모던EmberJS (Octane)에서는
productName
속성을 @tracked decorator 으로 표시해야 값이 변경되면 템플릿에서 업데이트됩니다.// controller.js
import Controller from '@ember/controller';
import { action } from '@ember/object';
import { tracked } from '@glimmer/tracking';
export default class ApplicationController extends Controller {
@tracked productName = 'foo';
@action updateProductName(newValue) {
console.log(
`productName was '${this.productName}'`,
`updating to '${newValue}'`
);
this.productName = newValue;
}
}
이제
productDetails
값을 사용하고 계산 비용이 많이 드는 파생 속성 productName
( via native ES6 getter )을 만들고 싶다고 가정해 보겠습니다. 해당 속성은 아마도 캐시되어야 합니다. Ember에서 이를 수행하는 표준 방법은 @cached decorator 입니다.// controller.js
import Controller from '@ember/controller';
import { action } from '@ember/object';
import { tracked, cached } from '@glimmer/tracking';
export default class ApplicationController extends Controller {
@tracked productName = 'foo';
@cached
get productDetails() {
console.log(
`updating productDetails because`,
`productName was updated to '${this.productName}'`
);
// .. Some expensive computation
return `Expensive cache of ${this.productName}`;
}
@action updateProductName(newValue) {
console.log(
`productName was '${this.productName}'`,
`updating to '${newValue}'`
);
this.productName = newValue;
}
}
문제
이제 사용자가 버튼을 여러 번 클릭하면 어떻게 될까요?
나는 다소 순진하게도 "상세 정보 로그"가 한 번만 나타날 것으로 예상했습니다. 첫 번째 클릭 후
productName
를 foo
에서 bar
로 업데이트했습니다. 두 번째 및 이후의 각 클릭은 bar
를 bar
로 다시 덮어씁니다. 실제로 값을 변경하지 않습니다. 따라서 @tracked
는 더티로 표시할 필요가 없으며 @cached
를 다시 계산할 필요가 없습니다. 오른쪽?잘못된. 결과적으로
@tracked
는 자신의 이전 값이 무엇인지 상관하지 않습니다. 업데이트를 시도한 것만 중요합니다.수정: Ben Demboskinoted on Discord:
@tracked properties get dirtied when you write to them, period
productDetails
의 계산이 정말 비싸고 productName
의 값이 변경되지 않으면 다시 실행되지 않도록 하고 싶다고 가정해 보겠습니다. 그렇게하는 방법?해결책
수동
해결책은 값이 변경되지 않았을 때 업데이트하지 않는 것입니다
productName
. @action updateProductName(newValue) {
if(this.productName !== newValue) {
this.productName = newValue;
}
}
애드온 사용
커뮤니티의 모든 것과 마찬가지로 가려움증이 있으면 누군가 곧 스크래처를 다시 만들 것입니다. tracked-toolbox addon을 설치하면 다음 설명이 있는 @dedupeTracked 데코레이터를 얻게 됩니다.
Turns a field in a deduped @tracked property. If you set the field to the same value as it is currently, it will not notify a property change (thus, deduping property changes). Otherwise, it is exactly the same as @tracked.
따라서 코드는 다음으로만 변경하면 됩니다.
// controller.js
import { dedupeTracked } from 'tracked-toolbox';
...
@dedupeTracked productName = 'foo';
...
결론
Pexels의 Andrea Piacquadio님의 사진
Reference
이 문제에 관하여(@cached는 언제 EmberJS에서 다시 계산됩니까?), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/michalbryxi/when-does-cached-get-recomputed-in-emberjs-58k6텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)