问题
I have just started switching from javascript to typescipt. I am using knockout for obvious advantages it has to offer.
I need to define a knockout computed observable which is dependent on the value of another knockout observable. Return true if the observable is valid else return false.
This is how I have structured the code -
class anyClass {
private address: KnockoutObservable<any> = ko.observable().extend({ required : true});
private canPrintAddresses : KnockoutComputed<boolean> = ko.computed((): any => {
if (this.address.isValid()) {
return true;
}
else
return false;
});
}
I even tried to define the computed inside the constructor, but the compiler is indifferent. I don't know where I am going wrong, but the compiler keeps on giving error - "property 'isValid' does not exist on type 'KnockoutObservable'".
Since, I am also using durandal, so I tried to define it inside the activate event handler, but then this requires the evaluation to be done on the activation of the page when there is no value attached to the observable.
Please help.
回答1:
The compiler is correct. In knockout, property 'isValid' indeed does not exist on KnockoutObservable.
Let's have a look at the knockout.d.ts file which ships with knockout:
interface KnockoutObservable<T> extends KnockoutSubscribable<T>, KnockoutObservableFunctions<T> {
(): T;
(value: T): void;
peek(): T;
valueHasMutated?: { (): void; };
valueWillMutate?: { (): void; };
extend(requestedExtenders: { [key: string]: any; }): KnockoutObservable<T>;
}
interface KnockoutSubscribable<T> extends KnockoutSubscribableFunctions<T> {
subscribe(callback: (newValue: T) => void, target?: any, event?: string): KnockoutSubscription;
subscribe<TEvent>(callback: (newValue: TEvent) => void, target: any, event: string): KnockoutSubscription;
extend(requestedExtenders: { [key: string]: any; }): KnockoutSubscribable<T>;
getSubscriptionsCount(): number;
}
interface KnockoutSubscribableFunctions<T> {
notifySubscribers(valueToWrite?: T, event?: string): void;
}
Notice, there is no "isValid".
So the question is: What makes you think isValid should be a valid member on an observable? If I had to guess, I'd guess you're using the knockout-validation library which adds extra features for form validation to knockout. If I'm guessing correctly, then I'd also guess that you did not bring in the type definitions files for that library. That library extends the KnockoutSubscribableFunctions<T>
interface to include more functionality, including isValid()
.
interface KnockoutSubscribableFunctions<T> {
isValid: KnockoutComputed<boolean>;
isValidating: KnockoutObservable<boolean>;
rules: KnockoutObservableArray<KnockoutValidationRule>;
isModified: KnockoutObservable<boolean>;
error: KnockoutComputed<string>;
setError(error: string): void;
clearError(): void;
}
Once you include those type definitions, you should be good to go. They are available at the definitely typed repository:
https://github.com/borisyankov/DefinitelyTyped/blob/master/knockout.validation/knockout.validation.d.ts
回答2:
The "address" is an observable variable. It stores an object. You should use
if (this.address().isValid()) {
or
if (ko.unwrap(this.address).isValid()) {
in order to access stored object's properties.
Of course if you want to get value from an observable, you should put the value in the observable before, e.g.:
this.address({ isValid: ko.observable(true) });
来源:https://stackoverflow.com/questions/33013634/property-isvalid-does-not-exist-on-type-knockoutobservable