简体   繁体   English

将ENUM与Typescript和Knockout结合使用

[英]Using ENUM with Typescript and Knockout

I am trying to create a basic login screen, as I learn Knockout and TypeScript. 在学习Knockout和TypeScript时,我试图创建一个基本的登录屏幕。 I am trying to add a 'PageMode' enum that allows knockout to know what mode we're in and data bind to the pageMode property to display things correctly. 我正在尝试添加一个'PageMode'枚举,该枚举允许淘汰赛知道我们处于哪种模式,并将数据绑定到pageMode属性以正确显示内容。 However, when the screen loads, 'pageMode' is undefined. 但是,在屏幕加载时,“ pageMode”是未定义的。 How can I get this to work? 我该如何工作?

I have created 2 models, which will be used by the knockout View Model (Login and Register), and an enum for PageMode. 我已经创建了2个模型,这些模型将由敲除视图模型(登录和注册)以及一个用于PageMode的枚举使用。

In design time, pageMode is visiable - but when I run it, it fails as pageMode is undefined. 在设计时,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());

On the HTML side, I was hoping to make divs visible via this: 在HTML方面,我希望通过以下方法使div可见:

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

However, that might be an issue too, as I don't think the page will know about the enum? 但是,这也可能是一个问题,因为我不认为页面会知道该枚举吗?

This actually does work. 这确实有效。 The error 'pageMode' is undefined originates from the fact that pageMode is not instantiated on HomeViewModel 错误'pageMode' is undefined是由于未在HomeViewModel实例化pageMode导致的

So change 所以改变

pageMode: KnockoutObservable<PageMode>;

to

pageMode = ko.observable<PageMode>();

In the example below, the typescript is converted to javascript: 在下面的示例中,打字稿被转换为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> 

A Knockout binding can access properties on the viewmodel, global variables, and properties of the binding context. 敲除绑定可以访问视图模型的属性,全局变量和绑定上下文的属性。 So a simple solution is to make sure enums are stored globally: 因此,一个简单的解决方案是确保枚举存储在全局范围内:

window.PageMode = PageMode;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM