WebComponents - 属性已更改

时间:2016-12-16 18:07:56

标签: javascript html web-component custom-element

从链接qr-code.js我有以下代码。

然后我不明白,在highlighted line (60)上,后缀是什么意思:"更改"?

attributeChangedCallback: {
    value: function (attrName, oldVal, newVal) {
        var fn = this[attrName+'Changed'];
        if (fn && typeof fn === 'function') {
            fn.call(this, oldVal, newVal);
        }
        this.generate();
    }

另外,我不了解使用:

this[attrName+'Changed']

你能解释一下这个吗?我在谷歌上找不到任何明确的解释。感谢。

以下是完整代码:

'use strict';

(function(definition) {
    if (typeof define === 'function' && define.amd) {
        define(['QRCode'], definition);
    } else if (typeof module === 'object' && module.exports) {
        var QRCode = require('qrjs');
        module.exports = definition(QRCode);
    } else {
        definition(window.QRCode);
    }
})(function(QRCode) {
//
// Prototype
//
var proto = Object.create(HTMLElement.prototype, {
    //
    // Attributes
    //
    attrs: {
        value: {
            data: null,
            format: 'png',
            modulesize: 5,
            margin: 4
        }
    },
    defineAttributes: {
        value: function () {
            var attrs = Object.keys(this.attrs),
                attr;
            for (var i=0; i<attrs.length; i++) {
                attr = attrs[i];
                (function (attr) {
                    Object.defineProperty(this, attr, {
                        get: function () {
                            var value = this.getAttribute(attr);
                            return value === null ? this.attrs[attr] : value;
                        },
                        set: function (value) {
                            this.setAttribute(attr, value);
                        }
                    });
                }.bind(this))(attr);
            }
        }
    },
    //
    // LifeCycle Callbacks
    //
    createdCallback: {
        value: function () {
            this.createShadowRoot();
            this.defineAttributes();
            this.generate();
        }
    },
    attributeChangedCallback: {
        value: function (attrName, oldVal, newVal) {
            var fn = this[attrName+'Changed'];
            if (fn && typeof fn === 'function') {
                fn.call(this, oldVal, newVal);
            }
            this.generate();
        }
    },
    //
    // Methods
    //
    getOptions: {
        value: function () {
            var modulesize = this.modulesize,
                margin = this.margin;
            return {
                modulesize: modulesize !== null ? parseInt(modulesize) : modulesize,
                margin: margin !== null ? parseInt(margin) : margin
            };
        }
    },
    generate: {
        value: function () {
            if (this.data !== null) {
                if (this.format === 'png') {
                    this.generatePNG();
                }
                else if (this.format === 'html') {
                    this.generateHTML();
                }
                else if (this.format === 'svg') {
                    this.generateSVG();
                }
                else {
                    this.shadowRoot.innerHTML = '<div>qr-code: '+ this.format +' not supported!</div>'
                }
            }
            else {
                this.shadowRoot.innerHTML = '<div>qr-code: no data!</div>'
            }
        }
    },
    generatePNG: {
        value: function () {
            try {
                var img = document.createElement('img');
                img.src = QRCode.generatePNG(this.data, this.getOptions());
                this.clear();
                this.shadowRoot.appendChild(img);
            }
            catch (e) {
                this.shadowRoot.innerHTML = '<div>qr-code: no canvas support!</div>'
            }
        }
    },
    generateHTML: {
        value: function () {
            var div = QRCode.generateHTML(this.data, this.getOptions());
            this.clear();
            this.shadowRoot.appendChild(div);
        }
    },
    generateSVG: {
        value: function () {
            var div = QRCode.generateSVG(this.data, this.getOptions());
            this.clear();
            this.shadowRoot.appendChild(div);
        }
    },
    clear: {
        value: function () {
            while (this.shadowRoot.lastChild) {
                this.shadowRoot.removeChild(this.shadowRoot.lastChild);
            }
        }
    }
});
//
// Register
//
document.registerElement('qr-code', {
    prototype: proto
});
});

1 个答案:

答案 0 :(得分:0)

正如@Jhecht建议的那样,它是属性名称和后缀“Changed”的组合,以便创建通用方法名称。

例如,如果<qr-code>元素的属性“foo”已添加,更新或删除,则回调会将fn变量定义为this["fooChanged"],这相当于this.fooChange

如果此方法存在,则fn.call()将调用它。

但是我发现在你发布的代码中没有任何地方附加到自定义元素原型的方法签名,所以它是无用的代码,直到另行通知。