从Javascript转换为Typescript、Knockout和DevExtreme控件
我在从Javascript转换到Typescript时遇到了一些问题,尤其是在创建devextreme控件时 过去,我会在我的viewmodel中为devextreme控件创建一个对象,如下所示:从Javascript转换为Typescript、Knockout和DevExtreme控件,typescript,knockout.js,devextreme,Typescript,Knockout.js,Devextreme,我在从Javascript转换到Typescript时遇到了一些问题,尤其是在创建devextreme控件时 过去,我会在我的viewmodel中为devextreme控件创建一个对象,如下所示: self.myButton = { text: 'Click Me', disabled: ko.purecomputed(function(){ return self.myobservable().length>0;}); } 这很好用,我试过用打字机 myButton: DevE
self.myButton = {
text: 'Click Me',
disabled: ko.purecomputed(function(){ return self.myobservable().length>0;});
}
这很好用,我试过用打字机
myButton: DevExpress.ui.dxButtonOptions;
然后在构造函数中
....
self.myButton = {
text: 'Click Me',
disabled: ko.purecomputed(function(){ return self.myobservable().length>0;});
}
...
这给了我一个错误类型KnockoutComputed不能分配给boolean类型,这很公平,我得到了这个
但问题是,应该如何做到这一点
我可以用这个:
myButton: any;
在按钮选项的声明中,但我认为这有点违背了使用typescript的目的
这是可行的,使用typescript的原因之一就是要使用像webpack之类的东西,所以这不是完全的损失,我只是想知道如何正确地做到这一点
提前感谢。我已经检查了使用和解决您的问题的可能性。然而,我认为最干净的方法是简单地使用任何类型的小部件选项 两个示例的模板相同:
<div data-bind="dxButton: buttonOptions"></div>
一个想法是:您可以尝试使用
keyof
并扩展DevExpress
接口,将KnockoutComputed&T
作为值。作为一个选项,您可以将其用于属性。在这种情况下,属性将具有简单的类型,并可用于DevExtreme的选项。@unional您能给我一些关于如何在devexpress界面上使用keyof的示例吗?我对typescript不太熟悉,所以不知道从何处开始?@mykhailo.romaniuk谢谢您提供的链接,我从未见过这个,但它看起来确实不错。但有一个问题是,如果我要这么做,我是否必须将我的pureCompute分解成一个单独的vm方法?@jasoncley我玩了一点,他们似乎无法解决您的问题。我也想过使用这个库,但是所有解决这个库问题的方法对我来说都是一种解决方法。我不得不说,我认为没有比使用任何控件选项更好的方法了
// importing thing from DevExtreme.
import "devextreme/ui/button";
import DevExpress from "devextreme/bundles/dx.all";
import * as ko from "knockout";
// importing knockout-es5 to include track and defineProperty functionality
import "knockout-es5";
// This small util will make creation of compute a bit more strong by using keyof
const createComputed = <T>(prototype: T, key: keyof T, computedFunc: Function): void => {
ko.defineProperty(prototype, key, computedFunc);
}
class DevextremeTestViewModel {
clickCounter: number = 0;
buttonOptions: DevExpress.ui.dxButtonOptions;
constructor() {
this.buttonOptions = {
text: "Start",
onClick: this.increaseCounter
};
// start tracking clickCounter property (make it observable)
ko.track(this, ["clickCounter"]);
// assign to text property of widget options computed value
createComputed(this.buttonOptions, "text", () => {
return `Clicked ${this.clickCounter} times`;
});
}
increaseCounter(): void {
this.clickCounter++;
}
}
import "devextreme/ui/button";
import DevExpress from "devextreme/bundles/dx.all";
// include required decorators
import { observable, computed } from "knockout-decorators";
// Magic function to copy getter from one property to another
const copyGetter = <T, TProp>(prototype: T, key: keyof T, propProto: TProp, propertyKey: keyof TProp) => {
let getter = Object.getOwnPropertyDescriptor(propProto, propertyKey).get;
Object.defineProperty(prototype, key, {
get: getter
});
}
class DevextremeTestViewModel {
// Create observable
@observable clickCounter: number = 0;
// Create computed that based on observable
@computed({ pure: true }) get buttonText(): string {
return `Clicked ${this.clickCounter} times`;
};
buttonOptions: DevExpress.ui.dxButtonOptions;
constructor() {
this.buttonOptions = {
text: this.buttonText,
onClick: this.increaseCounter
};
// Need to copy getter from our computed to options property.
copyGetter(this.buttonOptions, "text", this, "buttonText");
}
increaseCounter(): void {
this.clickCounter++;
}
}
import "devextreme/ui/button";
import DevExpress from "devextreme/bundles/dx.all";
import { observable, computed } from "knockout-decorators";
import * as ko from "knockout";
class DevextremeTestViewModel {
// Create observable
@observable clickCounter: number = 0;
buttonOptions: any = {
text: ko.pureComputed(()=> {
return `Clicked ${this.clickCounter} times`;
}),
onClick: this.increaseCounter
};
increaseCounter(): void {
this.clickCounter++;
}
}