【问题标题】:Using ENUM with Typescript and Knockout将 ENUM 与 Typescript 和 Knockout 一起使用
【发布时间】:2017-03-02 01:09:09
【问题描述】:

我正在尝试创建一个基本的登录屏幕,因为我正在学习 Knockout 和 TypeScript。我正在尝试添加一个“PageMode”枚举,它允许敲除知道我们所处的模式并将数据绑定到 pageMode 属性以正确显示内容。但是,当屏幕加载时,'pageMode' 是未定义的。我怎样才能让它工作?

我创建了 2 个模型,它们将被淘汰视图模型(登录和注册)使用,以及一个用于 PageMode 的枚举。

在设计时,pageMode 是可见的 - 但是当我运行它时,它会因为 pageMode 未定义而失败。

class LoginModel {
    emailAddress: KnockoutObservable<string>;
    password: KnockoutObservable<string>;
    rememberMe: KnockoutObservable<boolean>;

    constructor() {
        this.emailAddress = ko.observable("");
        this.password = ko.observable("");
        this.rememberMe = ko.observable(false);
    }
} 

class RegisterModel {
    emailAddress: KnockoutObservable<string>;
    password: KnockoutObservable<string>;
    passwordRetry: KnockoutObservable<string>;

    constructor() {
        this.emailAddress = ko.observable("");
        this.password = ko.observable("");
        this.passwordRetry = ko.observable("");
    }
}


enum PageMode {
    LoggingIn,
    RecoveringPassword,
    Registering
}

class ForgotPassword {
    emailAddress: KnockoutObservable<string>;
}

class HomeViewModel {

    login: LoginModel;
    register: RegisterModel;
    pageMode: KnockoutObservable<PageMode>;

    isLoginEnabled: KnockoutComputed<boolean>;

    constructor() {
        this.pageMode(PageMode.LoggingIn);
        this.login = new LoginModel();
        this.register = new RegisterModel();

        this.isLoginEnabled = ko.computed(() => {
            return !!this.login.emailAddress() && !!this.login.password();
        });

    }

    ShowRecoverPassword()
    {
        this.pageMode(PageMode.RecoveringPassword);
    }

    ShowRegister()
    {
        this.pageMode(PageMode.Registering);
    }

    ShowLogin()
    {
        this.pageMode(PageMode.LoggingIn);
    }




}

ko.applyBindings(new HomeViewModel());

在 HTML 方面,我希望通过以下方式使 div 可见:

<div id="register-box" data-bind="visible: pageMode() == PageMode.Registering">

但是,这也可能是一个问题,因为我认为页面不会知道枚举?

【问题讨论】:

    标签: javascript typescript knockout.js enums


    【解决方案1】:

    这确实有效。错误 'pageMode' is undefined 源于 pageMode 未在 HomeViewModel 上实例化的事实

    所以改变

    pageMode: KnockoutObservable<PageMode>;
    

    pageMode = ko.observable<PageMode>();
    

    在下面的示例中,typescript 被转换为 javascript:

    var LoginModel = (function () {
        function LoginModel() {
            this.emailAddress = ko.observable("");
            this.password = ko.observable("");
            this.rememberMe = ko.observable(false);
        }
        return LoginModel;
    }());
    var RegisterModel = (function () {
        function RegisterModel() {
            this.emailAddress = ko.observable("");
            this.password = ko.observable("");
            this.passwordRetry = ko.observable("");
        }
        return RegisterModel;
    }());
    var PageMode;
    (function (PageMode) {
        PageMode[PageMode["LoggingIn"] = 0] = "LoggingIn";
        PageMode[PageMode["RecoveringPassword"] = 1] = "RecoveringPassword";
        PageMode[PageMode["Registering"] = 2] = "Registering";
    })(PageMode || (PageMode = {}));
    var ForgotPassword = (function () {
        function ForgotPassword() {
        }
        return ForgotPassword;
    }());
    var HomeViewModel = (function () {
        function HomeViewModel() {
            var _this = this;
            this.pageMode = ko.observable();
            this.pageMode(PageMode.LoggingIn);
            this.login = new LoginModel();
            this.register = new RegisterModel();
            this.isLoginEnabled = ko.computed(function () {
                return !!_this.login.emailAddress() && !!_this.login.password();
            });
        }
        HomeViewModel.prototype.ShowRecoverPassword = function () {
            this.pageMode(PageMode.RecoveringPassword);
        };
        HomeViewModel.prototype.ShowRegister = function () {
            this.pageMode(PageMode.Registering);
        };
        HomeViewModel.prototype.ShowLogin = function () {
            this.pageMode(PageMode.LoggingIn);
        };
        return HomeViewModel;
    }());
    ko.applyBindings(new HomeViewModel());
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
    <div id="register-box" data-bind="visible: pageMode() == PageMode.LoggingIn">Logging in</div>
    <div id="register-box" data-bind="visible: pageMode() == PageMode.Registering">Registering</div>
    <button data-bind="click: ShowRegister">Show register</button>

    【讨论】:

    • 。您建议的更改会导致设计时错误。如果不是 pageMode: KnockoutObservable = ko.observable(); ?
    • 那肯定也可以。据我所知,Typescript 的类型推断会使声明变得不必要
    【解决方案2】:

    Knockout 绑定可以访问视图模型上的属性、全局变量和绑定上下文的属性。所以一个简单的解决方案是确保枚举存储在全局范围内:

    window.PageMode = PageMode;
    

    【讨论】:

    • 我不得不使用window['PageMode'] = PageMode 来绕过 TS 呻吟,但它确实有效。谢谢!
    猜你喜欢
    • 2020-04-17
    • 2017-02-20
    • 1970-01-01
    • 2013-03-24
    • 2013-07-09
    • 1970-01-01
    • 2014-01-03
    • 2014-03-06
    • 1970-01-01
    相关资源
    最近更新 更多