Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

React实现双向数据绑定 #20

Open
Wscats opened this issue Aug 29, 2019 · 0 comments
Open

React实现双向数据绑定 #20

Wscats opened this issue Aug 29, 2019 · 0 comments

Comments

@Wscats
Copy link
Owner

Wscats commented Aug 29, 2019

利用Proxy对数据进行劫持,自动触发this.setState

import { define, WeElement, html, h, extend, get, set } from "omi";

export interface appOptions {
    name: string;
    view(props?: any, state?: any, ref?: any);
    state?: any;
    propTypes?: any;
    props?: any;
    defaultProps?: any;
    css?: string;
    install?(props?: any, state?: any, ref?: any);
    installed?(props?: any, state?: any, ref?: any);
    uninstall?(props?: any, state?: any, ref?: any);
    beforeUpdate?(props?: any, state?: any, ref?: any);
    updated?(props?: any, state?: any, ref?: any);
    beforeRender?(props?: any, state?: any, ref?: any);
    receiveProps?(props?: any, state?: any, ref?: any);
}

// Added code
const isObject = obj => Object.prototype.toString.call(obj) === '[object Object]';
// Added code
const observify = (obj, that) => {
    if (!isObject(obj)) {
        return obj;
    }
    Object.keys(obj).forEach(key => {
        obj[key] = observify(obj[key], that);
    });

    return Observer(obj, that);
}
// Added code
const Observer = (obj, that) => {
    return new Proxy(obj, {
        set(obj, prop, value) {
            const res = Reflect.set(obj, prop, value);
            that.update();
            return res;
        }
    });
}

const app = ({
    name,
    view,
    state,
    propTypes,
    props,
    defaultProps,
    css,
    install,
    installed,
    uninstall,
    beforeUpdate,
    updated,
    beforeRender,
    receiveProps
}: appOptions) => {
    define(name, class extends WeElement {
        state = Object.assign({}, state);

        static props = props;
        static propTypes = propTypes;
        static defaultProps = defaultProps;
        static css = css;
        private ref;

        constructor() {
            super();
            (that => {
                // Added code
                that.state = observify(that.state, that)
            })(this);
        }

        install() {
            install &&
                install(
                    this.props ? this.props : {},
                    this.state ? this.state : {},
                    this
                );
        }

        installed() {
            installed &&
                installed(
                    this.props ? this.props : {},
                    this.state ? this.state : {},
                    this
                );
        }

        uninstall() {
            uninstall &&
                uninstall(
                    this.props ? this.props : {},
                    this.state ? this.state : {},
                    this
                );
        }

        render(oProps, oState) {
            return view(
                this.props ? this.props : oProps,
                this.state ? this.state : oState,
                this
            );
        }
    });
};

extend("model", (el: any, path, scope) => {
    el.value = get(scope, path);
    el.addEventListener("input", () => {
        set(scope, path, el.value);
        scope.update();
    });
});

export { html, h, app };
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant