2016-05-13 10 views
0
hinzugefügt wurde

Ich versuche, mein zugrunde liegendes Datenobjekt zu modifizieren und die Fähigkeit auf der Seite zu erhalten, die neuen Spalten zu aktualisieren und anzuzeigen. Das Datenobjekt wird ordnungsgemäß aktualisiert, löst jedoch kein erneutes Rendern der Benutzeroberfläche aus.KnockoutJS - Spalte hinzufügen, wenn Eigenschaft zu Objekt

Was habe ich nicht verstanden?

http://jsfiddle.net/Xpx7f/198/

<table> 
    <thead> 
     <tr data-bind="foreach: columnNames"> 
      <th> <span data-bind="text: $data"></span> 

      </th> 
     </tr> 
    </thead> 
    <tbody data-bind="foreach: items"> 
     <tr data-bind="foreach: $parent.columnNames"> 
      <td><input data-bind="value: $parent[$data]"></td> 
     </tr> 
    </tbody> 
</table> 

Und das Javascript:

var vm; 

window.onload = function() { 
var VM = function() { 
    var self = this; 
    self.items = ko.observableArray(); 
    self.columnNames = ko.computed(function() { 
     if (self.items().length === 0) 
      return []; 
     var props = []; 
     var obj = self.items()[0]; 
     for (var name in obj) 
      props.push(name); 
     return props; 


    }); 

}; 
vm = new VM(); 

ko.applyBindings(vm); 

vm.items.push({ 
    'Name': 'John', 
    'Age': 25 
}); 
vm.items.push({ 
    'Name': 'Morgan', 
    'Age': 26 
}); 

// Add an extra property to each object 
for (var i = 0; i < vm.items().length; i++) { 
     vm.items()[i].Weight = '50kg'; 
} 
// ????? Table should update with new column 'Weight' 

} 
+0

Es gibt kein „neues“ Element in der beobachtbaren Array, also löst es kein Observables aus. Sie können versuchen, ein Update manuell auszulösen. – user3297291

Antwort

0

Sie sind nicht wirklich die beobachtbare aktualisieren, aber das Hinzufügen eines neuen Feldes enthält es zu widersprechen.

Versuchen Sie, vm.items.valueHasMutated(); zu verwenden, nachdem Sie einige Eigenschaften an Ihre Objekte im KO-Array angehängt haben.

var vm; 
 

 
window.onload = function() { 
 
    var VM = function() { 
 
    var self = this; 
 
    self.items = ko.observableArray(); 
 
    self.columnNames = ko.computed(function() { 
 
     if (self.items().length === 0) 
 
     return []; 
 
     var props = []; 
 
     var obj = self.items()[0]; 
 
     for (var name in obj) 
 
     props.push(name); 
 
     return props; 
 

 

 
    }); 
 

 
    }; 
 
    vm = new VM(); 
 

 
    ko.applyBindings(vm); 
 

 
    vm.items.push({ 
 
    'Name': 'John', 
 
    'Age': 25 
 
    }); 
 
    vm.items.push({ 
 
    'Name': 'Morgan', 
 
    'Age': 26 
 
    }); 
 

 
    for (var i = 0; i < vm.items().length; i++) { 
 
    vm.items()[i].Weight = '50kg'; 
 
    } 
 
    vm.items.valueHasMutated(); 
 

 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 
 
<table> 
 
    <thead> 
 
    <tr data-bind="foreach: columnNames"> 
 
     <th> <span data-bind="text: $data"></span> 
 

 
     </th> 
 
    </tr> 
 
    </thead> 
 
    <tbody data-bind="foreach: items"> 
 
    <tr data-bind="foreach: $parent.columnNames"> 
 
     <td> 
 
     <input data-bind="value: $parent[$data]"> 
 
     </td> 
 
    </tr> 
 
    </tbody> 
 
</table>

Was Sie hier machen wird im Wesentlichen die beobachtbare Array zu sagen, dass der Wert geändert hat, werden alle Abonnenten einmal benachrichtigt.

Wenn Sie bei der Umsetzung von Knockout beobachtbaren Array Push sehen Sie, dass mit jedem Druck sehen können, die gleiche Logik gilt - sie nennen die valueHasMutated()

ko.observableArray['fn']['push'] = function() { 
     // Use "peek" to avoid creating a subscription in any computed that we're executing in the context of 
     // (for consistency with mutating regular observables) 
     var underlyingArray = this.peek(); 
     this.valueWillMutate(); 
     this.cacheDiffForKnownOperation(underlyingArray, methodName, arguments); 
     var methodCallResult = underlyingArray[methodName].apply(underlyingArray, arguments); 
     this.valueHasMutated(); 
     // The native sort and reverse methods return a reference to the array, but it makes more sense to return the observable array instead. 
     return methodCallResult === underlyingArray ? this : methodCallResult; 
    }; 
Verwandte Themen