From 0a7bf8ac10550cf87c2b6f06d08948f3d3f1fdcc Mon Sep 17 00:00:00 2001 From: Ajai Shankar <328008+ajaishankar@users.noreply.github.com> Date: Tue, 17 Oct 2023 07:39:54 -0500 Subject: [PATCH] docs(v1.0.0): computed to getter --- README.md | 44 +++++++++++++---------------- docs/cart-controller.js | 43 ++++++++++++++-------------- docs/cart-item-controller.js | 11 ++++---- docs/index.html | 5 ++-- docs/lib/stimulus-reactive.js | 53 ----------------------------------- 5 files changed, 48 insertions(+), 108 deletions(-) diff --git a/README.md b/README.md index 510af23..e67d6b5 100644 --- a/README.md +++ b/README.md @@ -37,13 +37,13 @@ class CartItemController extends Controller { useStimulusReactive(identifier, application); } + get total() { + return this.priceValue * this.quantityValue; + } + connect() { - // item total will be updated when price or quantity changes - this.effect(() => { - this.totalTarget.textContent = ( - this.priceValue * this.quantityValue - ).toString(); - }); + // displayed total will be updated when price or quantity changes + this.effect(() => (this.totalTarget.textContent = this.total.toString())); } } @@ -55,23 +55,20 @@ class CartController extends Controller { useStimulusReactive(identifier, application); } + get total() { + return this.cartItemOutlets.reduce((total, item) => total + item.total, 0); + } + connect() { - // total will be updated when items get added or removed - // or when an item's price or quantity changes - const total = this.computed(() => - this.cartItemOutlets.reduce( - (total, item) => total + item.priceValue * item.quantityValue, - 0 - ) - ); - - // checkout button will be enabled only when balance is due - this.effect(() => (this.checkoutTarget.disabled = total.value <= 0)); - - // text content is kept in sync with cart total - this.effect( - () => (this.cartTotalTarget.textContent = total.value.toString()) - ); + this.effect(() => { + // text content is kept in sync with cart total + this.cartTotalTarget.textContent = total.toString() + // checkout button is enabled only when balance is due + this.checkoutTarget.disabled = total == 0 + }); + + // another effect for some other dependency + this.effect(() => ...); } } ``` @@ -81,10 +78,9 @@ class CartController extends Controller { State lives in a controller's values and connected outlets. 1. Call `useStimulusReactive` in the static `afterLoad` method -2. In the `connect` lifecycle method specify the controller logic using `effect` +2. In the `connect` lifecycle method specify controller behavior using `effect`s 3. Effects will run whenever any dependency changes This will be familiar to those coming from other frameworks like React, Vue etc. -4. Use `computed` (as needed) for any optimizations That's pretty much it! diff --git a/docs/cart-controller.js b/docs/cart-controller.js index 881089b..fcd95f2 100644 --- a/docs/cart-controller.js +++ b/docs/cart-controller.js @@ -6,6 +6,7 @@ export default class extends Controller { shipping: Number, taxRate: Number, }; + static targets = [ "checkout", "subtotal", @@ -20,34 +21,32 @@ export default class extends Controller { useStimulusReactive(identifier, application); } - connect() { - const subtotal = this.computed(() => - this.cartItemOutlets.reduce( - (total, item) => total + item.priceValue * item.quantityValue, - 0 - ) - ); + get subtotal() { + return this.cartItemOutlets.reduce((total, item) => total + item.total, 0); + } - const tax = this.computed(() => (subtotal.value * this.taxRateValue) / 100); + get tax() { + return (this.subtotal * this.taxRateValue) / 100; + } - const shipping = this.computed(() => - subtotal.value ? this.shippingValue : 0 - ); + get shipping() { + return this.subtotal ? this.shippingValue : 0; + } - const total = this.computed( - () => subtotal.value + tax.value + shipping.value - ); + get total() { + return this.subtotal + this.tax + this.shipping; + } + connect() { this.effect(() => { - this.subtotalTarget.textContent = subtotal.value.toFixed(2); - this.shippingTarget.textContent = shipping.value.toFixed(2); - this.taxTarget.textContent = tax.value.toFixed(2); - this.totalTarget.textContent = total.value.toFixed(2); - }); + this.subtotalTarget.textContent = this.subtotal.toFixed(2); + this.shippingTarget.textContent = this.shipping.toFixed(2); + this.taxTarget.textContent = this.tax.toFixed(2); + this.totalTarget.textContent = this.total.toFixed(2); - this.effect(() => { - this.checkoutTarget.disabled = total.value <= 0; - if (total.value > 0) { + this.checkoutTarget.disabled = this.total == 0; + + if (this.total > 0) { this.noItemsMessageTarget.classList.add("hidden"); } else { this.noItemsMessageTarget.classList.remove("hidden"); diff --git a/docs/cart-item-controller.js b/docs/cart-item-controller.js index 8d82440..bdfe3a3 100644 --- a/docs/cart-item-controller.js +++ b/docs/cart-item-controller.js @@ -12,13 +12,12 @@ export default class extends Controller { useStimulusReactive(identifier, application); } + get total() { + return this.priceValue * this.quantityValue; + } + connect() { - this.effect( - () => - (this.totalTarget.textContent = ( - this.priceValue * this.quantityValue - ).toFixed(2)) - ); + this.effect(() => (this.totalTarget.textContent = this.total)); } changeQuantity(e) { diff --git a/docs/index.html b/docs/index.html index 758f501..586d224 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1,6 +1,5 @@ - +
@@ -19,7 +18,7 @@ data-cart-shipping-value="5" data-cart-tax-rate-value="8.25">