简体   繁体   English

Ember Octane,跟踪属性不重新渲染模板

[英]Ember Octane, Tracked property not rerendering template

Coming from a React background, I'm having issues understanding EmberJs "Tracked" concept.来自 React 背景,我在理解 EmberJs“Tracked”概念时遇到了问题。 On paper it shouldn't be different from "React state".在纸面上它不应该与“反应状态”不同。

So what I have understood is that when we anotate a property with @tracked it should cause a re render when there is a change in this property.所以我的理解是,当我们用@tracked注释一个属性时,当这个属性发生变化时,它应该会导致重新渲染。

Please take a look at the code below:请看下面的代码:

ProductItemComponent ProductItem组件

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;
    }
  }
}

Template ,模板,

<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>

When I first render the component I'm checking if the current item is present in the cart using {{did-insert (fn this.checkItemInCart @item.id)}} and if its present I'm switch the tracked property @tracked addedToCart = false;当我第一次渲染组件时,我使用{{did-insert (fn this.checkItemInCart @item.id)}}检查购物车中是否存在当前商品,如果存在,我将切换跟踪属性@tracked addedToCart = false; to true else false.为真否则为假。

In theory, this should disable my button in my productItem template as soon as it finds the Item in the cartService .从理论上讲,这应该在我的 productItem 模板中一找到cartService中的 Item 就禁用我的按钮。 It only works when I go to another page and then come back.它仅在我 go 到另一个页面然后返回时才有效。

But there is no rerender of the page.但是页面没有重新呈现。 Can someone help me understand what I might be doing wrong?有人可以帮助我了解我可能做错了什么吗?

Thank you in advance先感谢您

Your problem is that checkItemInCart is called only once, so addedToCart is not updated once cartService.items were changed.您的问题是checkItemInCart只被调用一次,因此一旦更改cartService.items addedToCart就不会更新。

I think proper solution would be to make addedToCart depends on cartService.items and item我认为正确的解决方案是使addedToCart依赖于cartService.itemsitem

get addedToCart(){
  return !!this.cartService.items.findBy('id', this.args.item.id)
}

For this to work cartService.items should also be tracked property, and be updated with methods like pushObject , see Why won't my tracked array update in Ember Octane?为此, cartService.items也应该是 tracked 属性,并使用pushObject等方法进行更新,请参阅为什么我的跟踪数组不会在 Ember Octane 中更新?

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

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