marko/docs/widgets/upgrade-guide.md
2016-11-02 16:12:13 -06:00

3.5 KiB

Upgrade Guide

v4 to v5

Breaking changes

  • The onAfterUpdate lifecycle event was renamed to onUpdate
  • The init() constructor for a widget is only called once even if a widget is rerendered
  • When a nested widget is rerendered, it is no longer reinitialized.
  • Everything related to Dust has been removed.

New features

  • Integrated morphdom to more efficiently transform the existing DOM instead of replacing it entirely
  • Significant performance improvements
  • Code cleanup
  • Stable IDs for widgets that are not assigned a w-id
  • New lifecycle event: 'onRender'

v3 to v4

Breaking changes

  • Widget.prototype.render = function(input, out) { ... } is no longer allowed. Use Widget.prototype.renderer = function(input, out) { ... } or defineComponent(...) instead (recommended).
  • NOTE: this.widgets.foo has been removed since marko-widgets@^3

New features

  • Simpler syntax for defining widget types:

Old:

function Widget() {
    this.doSomething();
}

Widget.prototype = {
    doSomething: function() {

    }
};

module.exports = Widget;

New:

module.exports = require('marko-widgets').defineWidget({
    init: function() {
        this.doSomething();
    },

    doSomething: function() {

    }
});
  • Ability to define the widget and the renderer in the same JavaScript file:
module.exports = require('marko-widgets').defineComponent({
    template: require.resolve('./template.marko'),

    getTemplateData: function(state, input) {
        return {
            hello: 'world'
        };
    },

    init: function() {
        this.doSomething();
    },

    doSomething: function() {

    }
});
  • Support for stateful widgets (changing widget state causes a widget to be rerendered)
module.exports = require('marko-widgets').defineComponent({
    template: require.resolve('./template.marko'),

    getInitialState: function(input) {
        return {
            size: input.size || 'normal'
        };
    },

    getInitialBody: function(input) {
        return input.label || input.renderBody;
    },
    getTemplateData: function(state, input) {
        var rootAttrs = {};

        var classParts = ['app-button'];

        var type = 'button';

        var size = state.size;
        if (size !== 'normal') {
            classParts.push('app-button-' + size);
        }

        rootAttrs['class'] = classParts.join(' ');

        return {
            type: type,
            rootAttrs: rootAttrs
        };
    },
    setSize: function(size) {
        this.setState('size', size);
    },
    getSize: function() {
        return this.state.size;
    }
});

v2 to v3

With marko-widgets, this.widgets.foo is no longer support and this.widgets will be null. Instead, you should this.getWidget('foo').

v1 to v2

marko-widgets v2 introduced the potential for a circular dependency. To avoid problems, you should no longer use module.exports in your widget JavaScript module as shown below:

Old widget.js:

function Widget() {
    // ...
}

Widget.prototype = {
    // ...
};

module.exports = Widget;

New widget.js:

function Widget() {

}

Widget.prototype = {

};

exports.Widget = Widget;

You should also do the same for your UI component renderer:

Old renderer.js:

module.exports = function render(input, out) {
    // ...
}

New renderer.js:

exports.renderer = function(input, out) {
    // ...
}