7

Ich verwende Knockout, um ein Kurslisten-Auswahlwerkzeug zu implementieren. Ich verwende den folgenden Ansatz, um die Daten (MVC3/Razor) zu füllen, so dass ich, wenn das Ansichtsmodell anfänglich gefüllt ist, keine Probleme mit jedem KO-Array (d. H. CourseList, ScheduleList) habe. Wenn die anfängliche Auslastung vom Server jedoch null Zeilen zurückgibt, was bedeutet, dass die Eigenschaft 'scheduleList' des Viewmodels leer ist, ist es nicht möglich, Methoden wie .push() oder .removeAll() aufzurufen. Vermutlich bedeutet dies, dass das beobachtbare Array nie erstellt wurde, da es nichts gab, um es zu füllen. Wenn das Modell gefüllt ist, wird die ScheduleList-Eigenschaft mit einer Liste aufgefüllt. Was ist der beste Weg, um es zu instanziieren, wenn die MVC-Aktion es als leer zurückgibt? Es gibt ein JsFiddle, das es anzugehen scheint, aber wenn ich versuche, die Option "create" zu verwenden, wird mein gesamtes Modell leer dargestellt. Ich bin mir nicht sicher, was die Syntax der 'create' Option ist. Die jsFiddle ist hier: http://jsfiddle.net/rniemeyer/WQGVC/So initialisieren Sie ein Knockout-Viewmodel, wenn das ursprüngliche Viewmodel leer ist

// Get the data from the server 
var DataFromServer = @Html.Raw(Json.Encode(Model));  

// Data property in viewmodel 
var data = { 
    "CourseList": DataFromServer.CourseList , 
    "ScheduleList": DataFromServer.ScheduleList 
    }; 

$(function() { 
    // Populate Data property 
    viewModel.Data = ko.mapping.fromJS(data); 

    // ko.applyBindings(viewModel, mappingOptions);    
    ko.applyBindings(viewModel); 
}); 

Wenn der anfängliche Laden der Seite ScheduleList nicht bevölkert, dann wird der folgende Code einen Fehler wirft. Wenn die anfängliche Seitenladedaten enthalten sind, dann könnten Sie nennen .removeAll() und .push() usw.

var oneA= 'abc'; 

// push not working     
this.Data.ScheduleList.push(oneA); 

Antwort

9

Ihre Mapping-Parameter ein, um es so auf Schöpfung, Sie geben eine gewisse Struktur. Dann wird es die Updates für Sie tun.

Was wahrscheinlich passiert ist, dass Ihre DataFromServer tatsächlich keine ScheduleList Eigenschaft enthält überhaupt. Wenn es zugeordnet wird, wird daher eine entsprechende Eigenschaft nie erstellt. Der Mapper wird vorhandene Eigenschaften nur Observablen zuordnen.

Sie müssen in Ihren create Optionen für das Ansichtsmodell festlegen, leere Arrays hinzuzufügen, wenn eines der Arrays nicht festgelegt ist. Auf diese Weise wird Ihr Ansichtsmodell mit entsprechenden beobachtbaren Arrays enden.

Indem sichergestellt wird, dass CourseList oder ScheduleList ein Array ist, wird das gemappte Ansichtsmodell sie als observableArray Objekte abbilden, so dass Ihr Code wie erwartet funktioniert.

var DataFromServer = { 
    'CourseList': [1,2,3] 
    //, 'ScheduleList': [] 
}; 

var dataMappingOptions = { 
    'create': function (options) { 
     var data = options.data; 
     data.CourseList = data.CourseList || []; 
     data.ScheduleList = data.ScheduleList || []; 
     return ko.mapping.fromJS(data); 
    } 
}; 

viewModel.Data = ko.mapping.fromJS(DataFromServer, dataMappingOptions); 
+0

Danke! Dies ist genau das, was passiert und das löst das Problem. Interessant, dass die meisten der jsFiddles, die ich betrachtete, auf der Eigenschaft (Array selbst) wirkten, also hatte ich diesen Rückruf nicht versucht. Der andere von Ray vorgeschlagene Ansatz funktioniert auch. –

1
var data = { 
    CourseList: DataFromServer.CourseList || ko.observableArray([]) , 
    ScheduleList: DataFromServer.ScheduleList || ko.observableArray([]) 
    }; 
Verwandte Themen