Nativescript类实现了observables默认的setter行为

Aar*_*lal 1 typescript nativescript

我正在看看nativescript hello world typescript repo,我遇到了一些与nativescript实现的observable一样乏味的工作.

如果查看视图模型的定义方式,可以看到它是一个只扩展Observable库的类.无论何时setter为属性定义方法,都需要手动调用super.notifyPropertyChange("propertyName", propertyValue);

恕我直言,如果你有具有许多属性的视图模型,这个过程非常低效且容易出错.

有没有办法自动完成这项任务?(也许有一个告诉任何setter的基类notifyPropertyChange?)如果没有,你是如何处理这个问题的?该Observable机制还有其他实现吗?

Pet*_*aev 7

以下是我在几个制作应用中使用的内容:

import { Observable } from "data/observable";

export class ObservableModel extends Observable {
    constructor() {
        super();
    }

    public get(propertyName: string) {
        return this["_" + propertyName];
    }

    public set(propertyName: string, value) {
        if (this["_" + propertyName] === value) {
            return;
        }

        this["_" + propertyName] = value;
        this.refresh(propertyName);
    }

    public refresh(propertyName: string) {
        super.notify({
            eventName: Observable.propertyChangeEvent,
            propertyName,
            object: this,
            value: this["_" + propertyName],
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你的模型看起来像:

export class LoginViewModel extends ObservableModel {
    get userName(): string { return this.get("userName"); }
    set userName(val: string) { this.set("userName", val); }

    get password(): string { return this.get("password"); }
    set password(val: string) { this.set("password", val); }
}
Run Code Online (Sandbox Code Playgroud)

当您需要使用您刚才使用的值时:

const vm = new LoginViewModel();
vm.userName = "jdoe";
vm.password = "$3cr3T";
Run Code Online (Sandbox Code Playgroud)

更新 装饰器实现:

export function ObservableProperty() {
    return (target: Observable, propertyKey: string) => {
        Object.defineProperty(target, propertyKey, {
            get: function () {
                return this["_" + propertyKey];
            },
            set: function (value) {
                if (this["_" + propertyKey] === value) {
                    return;
                }

                this["_" + propertyKey] = value;
                this.notify({
                    eventName: Observable.propertyChangeEvent,
                    propertyName: propertyKey,
                    object: this,
                    value,
                });
            },
            enumerable: true,
            configurable: true
        });
    };
}
Run Code Online (Sandbox Code Playgroud)

模型:

export class LoginViewModel extends Observable {
    @ObservableProperty() public userName: string;
    @ObservableProperty() public password: string;
}
Run Code Online (Sandbox Code Playgroud)