Ember Octane, Tracked 属性 不重新渲染模板
Ember Octane, Tracked property not rerendering template
来自 React 背景,我在理解 EmberJ 的“跟踪”概念时遇到问题。
在纸面上它应该与“反应状态”没有什么不同。
所以我的理解是,当我们用 @tracked
注释 属性 时,当此 属性.[=18= 发生变化时,它应该会导致重新渲染]
请看下面的代码:
ProductItemComponent
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { inject as service } from '@ember/service';
import { action } from '@ember/object';
export default class ProductItemIndexComponent extends Component {
@service('cart') cartService;
@tracked addedToCart = false;
@action
checkItemInCart(id) {
if (this.cartService.items.findBy('id', id)) {
this.addedToCart = true;
} else {
this.addedToCart = false;
}
}
}
模板,
<div class="card-container">
<div class="card product-item" {{did-insert (fn this.checkItemInCart @item.id)}}>
<img src={{@item.image}} class="product-image card-img-top" alt="...">
<div class="card-body">
<h5>{{@item.title}}</h5>
</div>
<div class="footer">
<p class="card-text"><span class="badge badge-secondary"><strong>Price: </strong>{{@item.price}}</span></p>
<button type="button" class="btn btn-warning" {{on 'click' (fn @handleCartAction item)}}
disabled={{this.addedToCart}}>Add
to cart</button>
</div>
</div>
</div>
当我第一次渲染组件时,我使用 {{did-insert (fn this.checkItemInCart @item.id)}}
检查购物车中是否存在当前项目,如果存在,我将切换跟踪 属性 @tracked addedToCart = false;
为真否则为假。
理论上,一旦在 cartService
中找到项目,这应该会在我的 productItem 模板中禁用我的按钮。它只在我转到另一个页面然后返回时有效。
但是页面没有重新呈现。有人可以帮助我了解我可能做错了什么吗?
提前致谢
您的问题是 checkItemInCart
只被调用一次,因此 addedToCart
在 cartService.items
被更改后不会更新。
我认为正确的解决方案是使 addedToCart
取决于 cartService.items
和 item
get addedToCart(){
return !!this.cartService.items.findBy('id', this.args.item.id)
}
要使其正常工作 cartService.items
还应跟踪 属性,并使用 pushObject
等方法进行更新,请参阅
来自 React 背景,我在理解 EmberJ 的“跟踪”概念时遇到问题。 在纸面上它应该与“反应状态”没有什么不同。
所以我的理解是,当我们用 @tracked
注释 属性 时,当此 属性.[=18= 发生变化时,它应该会导致重新渲染]
请看下面的代码:
ProductItemComponent
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { inject as service } from '@ember/service';
import { action } from '@ember/object';
export default class ProductItemIndexComponent extends Component {
@service('cart') cartService;
@tracked addedToCart = false;
@action
checkItemInCart(id) {
if (this.cartService.items.findBy('id', id)) {
this.addedToCart = true;
} else {
this.addedToCart = false;
}
}
}
模板,
<div class="card-container">
<div class="card product-item" {{did-insert (fn this.checkItemInCart @item.id)}}>
<img src={{@item.image}} class="product-image card-img-top" alt="...">
<div class="card-body">
<h5>{{@item.title}}</h5>
</div>
<div class="footer">
<p class="card-text"><span class="badge badge-secondary"><strong>Price: </strong>{{@item.price}}</span></p>
<button type="button" class="btn btn-warning" {{on 'click' (fn @handleCartAction item)}}
disabled={{this.addedToCart}}>Add
to cart</button>
</div>
</div>
</div>
当我第一次渲染组件时,我使用 {{did-insert (fn this.checkItemInCart @item.id)}}
检查购物车中是否存在当前项目,如果存在,我将切换跟踪 属性 @tracked addedToCart = false;
为真否则为假。
理论上,一旦在 cartService
中找到项目,这应该会在我的 productItem 模板中禁用我的按钮。它只在我转到另一个页面然后返回时有效。
但是页面没有重新呈现。有人可以帮助我了解我可能做错了什么吗?
提前致谢
您的问题是 checkItemInCart
只被调用一次,因此 addedToCart
在 cartService.items
被更改后不会更新。
我认为正确的解决方案是使 addedToCart
取决于 cartService.items
和 item
get addedToCart(){
return !!this.cartService.items.findBy('id', this.args.item.id)
}
要使其正常工作 cartService.items
还应跟踪 属性,并使用 pushObject
等方法进行更新,请参阅