8

What is the proper way to initialize a Knockout observableArray in a TypeScript class?

I am doing something like this:

   module ViewModel { 

        declare var ko;

        export class IndexPageViewModel {       

                agencies: any;                   

                constructor () {               
                    this.agencies = ko.observableArray([]);              
                }                                                                                                   
        }
    }


var ivm = new ViewModel.IndexPageViewModel();
ivm.agencies.push({name: "name", alias : "alias"});
for (var i = 0; i < ivm.agencies.length; i++){
    alert(ivm.agencies[i].name);
 }

Looks simple enough, but when I attempt to access the agencies property as indicated, execution hangs. Did I miss something?

2 Answers 2

13

This line is where your mistake is:

agencies[i]

When you access an observable array, it is actually wrapped in a function so you do access it like:

agencies()[i]

Also make yourself a favor and download the Knockout definitions from: https://github.com/borisyankov/DefinitelyTyped

Then declare your attributes with types:

module ViewModel {

    export class IndexPageViewModel {

        agencies: KnockoutObservableArray;

        constructor () {
            this.agencies = ko.observableArray([]);
        }
    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

That was it, thank you. Additional thanks for the link to all of the Typescript definitions.
Actually, accessing an observableArray is not entirely consistent. If you add items to the collection using this.agencies().push(anAgency), change notifications are not fired. But if you do this.agencies.push(anAgency), notifications are fired.
@KNji it is consistent. If you call a method on this.agencies you are accessing the KO wrapper around your array. Hence any changes will be noted and an event will be fired. If you invoke this.agencies() you resolve the observable and hence will get the underlying array as a result. Pushing objects directly on this array wil bypass the KO framework and thus no change event is fired.
5

I just did this in TypeScript 1.3 (though it should work in older versions too):

pendingAddAssociations: KnockoutObservableArray<ControllerModel> = ko.observableArray<ControllerModel>([]);

for your example, if you have an Agency class.

export class IndexPageViewModel {

        agencies: KnockoutObservableArray<Agency>;

        constructor () {
            this.agencies = ko.observableArray<Agency>([]);
        }
    }

I've also found that you can cast to any this.agencies = <any>[]; This is useful if you are using the Knockout ES5 plugin.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.