Magento 2 – How Does initObservable Function Work?

javascriptknockoutjsmagento2uicomponent

How does Magento 2's initObservable function work?

The more detail the better as I feel not many people understand the KO implementation and with the checkout being built with it I think it's something we really should know more about. The dev docs are currently not helpful at all when it comes to KO and with it being customised the KO website doesn't help either.

Alan Storm has written some excellent articles on M2 and KO but even these don't explain how initObservable works.

All the code below is inside

 vendor/magento/module-ui/view/base/web/js/lib/core/element/element.js

I'm doing some digging into Magento 2's Knockout implementation and I can gather this code loops through each element passed to it and fires track.

    initObservable: function () {
        _.each(this.tracks, function (enabled, key) {
            if (enabled) {
                this.track(key);
            }
        }, this);

        return this;
    },

The track function then calls the observe function:

    track: function (properties) {
        this.observe(true, properties);

        return this;
    },

The observe function then works it's magic, this is where I get lost as nothing here seems reference knockout at all.

    observe: function (useAccessors, properties) {
        var model = this,
            trackMethod;

        if (typeof useAccessors !== 'boolean') {
            properties   = useAccessors;
            useAccessors = false;
        }

        trackMethod = useAccessors ? accessor : observable;

        if (_.isString(properties)) {
            properties = properties.split(' ');
        }

        if (Array.isArray(properties)) {
            properties.forEach(function (key) {
                trackMethod(model, key, model[key]);
            });
        } else if (typeof properties === 'object') {
            _.each(properties, function (value, key) {
                trackMethod(model, key, value);
            });
        }

        return this;
    },

Best Answer

The initObservable method sets up variable tracking, as described in this article. In short: this lets you make an property a Knockout observable property by listing it as a tracks default. Knockout observable properties can update the UI automatically whenever they, themselves, are updated.

The initObservable method is called in the uiElement's initialize method. The initialize method is a __constructor/_construct style method for Magento's custom javascript object system.

#File: vendor/magento/module-ui/view/base/web/js/lib/core/element/element.js
initialize: function () {
    this._super()
        .initObservable()
        .initModules()
        .initStatefull()
        .initLinks()
        .initUnique();

    return this;
},

If you're curious about this object system, the UI Components and uiElement Internals series are a good place to start.

Related Topic