2017-12-14 1 views
1

Ich stoße auf ein Problem, wo ich Funktionen nicht verwenden kann, die ich in meinen Modellen in meiner Ansicht erklärt habe. Mir scheint, dass die Funktionen existieren, also bin ich mir nicht sicher, warum die Konsole mir sagt, dass sie nicht existieren.Knockout Typescript viewmodel Funktionen sind nicht definiert

Ich habe relevante Teile meines Erachtens hier extrahiert:

<div class="col-lg-6"> 
    <div class="page-header"> 
     <h3>Examens</h3> 
    </div> 
    <!-- ko foreach: examAttempts --> 
    <div class="panel-header clickable" data-bind="click:() => toggleOpen()"> 
     <h3 class="d-block"> 
      Examen poging #<span data-bind="text: $index"></span> 
      <span class="pull-right" data-bind="css: { fa: true, 'fa-chevron-left': !open(), 'fa-chevron-down': open() }"></span> 
     </h3> 
    </div> 
    <div class="panel-body" data-bind="visible: open"> 
     <!-- ko foreach: questions --> 
     <p> 
      <b><span data-bind="text: formatQuestion($index)"></span></b> 
      <br /> 
      <span data-bind="text: answer"></span> 
      <br /> 
      <i>Beantwoord in: <span data-bind="text: time"></span> seconde(s)</i> 
     </p> 
     <!-- /ko --> 
    </div> 
    <br /><br /><br /> 
    <!-- /ko --> 
</div> 

Diese meine Ansicht Modelle (weggelassen irrelevant Felder) sind:

class ExamAttempt { 
    questions: KnockoutObservableArray<ExamQuestion>; 
    open: KnockoutObservable<boolean>; 

    constructor(questions: any) { 
     this.questions = ko.observableArray<ExamQuestion>(questions); 
     this.open = ko.observable<boolean>(false); 
    } 

    public toggleOpen(): void { 
     this.open(!this.open()); 
    } 
} 

class ExamQuestion { 
    question: KnockoutObservable<string>; 
    answer: KnockoutObservable<string>; 
    time: KnockoutObservable<number>; 

    constructor(question: string, answer: string, time: number) { 
     this.question = ko.observable<string>(question); 
     this.answer = ko.observable<string>(answer); 
     this.time = ko.observable<number>(time); 
    } 

    public formatQuestion(index: number): string { 
     return `${index + 1}. ${this.question()}`; 
    } 
} 

class EditUserProfileModel { 
    examAttempts: KnockoutObservableArray<ExamAttempt>; 

    constructor(params: any) { 
     this.examAttempts = ko.observableArray<ExamAttempt>(params.examAttempts); 
    } 
} 

Anwenden von Bindungen (params ist die Seite Modell serialisierten):

ko.applyBindings(new EditUserProfileModel(params)); 

Die Fehler, die ich bekomme (gut, sie sagen nur die Funktion ns sind nicht definiert, aber mir scheint es, als wären sie nicht sein sollte):

enter image description here

Irgendwelche Vorschläge wäre sehr dankbar.

+0

Was ist 'params.examAttempts'? Handelt es sich um eine Sammlung einfacher JavaScript-Objekte oder werden sie mit 'new ExamAttempt()' erstellt? – adiga

+0

haben Sie versucht, die Lambda-Syntax für Ihre Funktion zu verwenden? So - public formatQuestion = (index: number): string => { gib '$ {index + 1} zurück. $ {this.question()} '; } – gkb

+0

Unrelated, aber es sollte wahrscheinlich 'index()' in js oder '$ index()' in Ihrem HTML – adiga

Antwort

0

Ja, ich habe es herausgefunden, es war ein Problem mit Typen. Obwohl params.examAttempts die gleiche Struktur und die gleichen Felder wie die ExamAttempt Klasse hat, wird sie von js/ts nicht in eine Instanz von ExamAttempt umgewandelt, was hier das Problem war (weil die Funktionen in der Klasse ExamAttempt definiert waren). Mein Fehler!.

@adiga, danke, dass du dir die Zeit genommen hast, eine Geige zu bauen.

es zu beheben, änderte ich diese Zeile:

this.examAttempts = ko.observableArray<ExamAttempt>(params.examAttempts) 

In:

this.examAttempts = ko.observableArray<ExamAttempt>(params.examAttempts.map((ea: any) => { 
    let questions = ea.questions.map((eaq: any) => { 
     return new ExamQuestion(eaq.question, eaq.answer, eaq.time); 
    }); 

    return new ExamAttempt(questions); 
})); 
Verwandte Themen