This is more pure KnockoutJS than it is Magento 2, but since I’m neck deep in KnockoutJS right now, a quickie it becomes.
I wrote about observables over on alanstorm.com because they’re a pretty important part of KnockoutJS, and Magento’s RequireJS programs use them like they were candy. I didn’t mention observable arrays, which are basically observables, that are arrays, with whose subscribers fire only when items are added and removed from the array.
This seems straight forward enough, but one thing that didn’t immediately click for me is any foreach
binding that users an observable array with re-render when a programmer updates the observable array. Probably because I have trouble thinking of foreach
as a binding since looping is such an atomic concept in programming.
A quick demonstration might be in order. If you navigate to Magento 2’s checkout page and enter an address, Magento should populate a few shipping rates automatically. If you pop open your javascript console and enter the following.
//fetch the shipping service require js module
service = requirejs('Magento_Checkout/js/model/shipping-service')
//fetch the rates, an observable array
ratesObservableArray = service.getShippingRates()
//view the rates
console.log(ratesObservableArray());
//remove one of the rates using the observable array
ratesObservableArray.pop()
After running the above code, you’ll notice Knockout’s automatically removed one of the shipping methods. That’s the power of an observable array. Because the Knockout template used a foreach
binding (and the rates()
method returns the same observable array as ratesObservableArray
above).
#File: vendor/magento/module-checkout/view/frontend/web/template/shipping.html
<!-- ko foreach: { data: rates(), as: 'method'} -->
<!-- ... -->
<!-- /ko -->
Knockout will re-render that foreach
section whenever you update the observable array.