0

Ich versuche, Inline-Bearbeitung mit Vorlagen zu implementieren. Auf meinem Viewmodel habe ich eine Methode: self.changeMode. Ich trigse das von einem Knopfklickereignis (innerhalb der Schablone) aus. Der Datenparameter, der an die Funktion changeMode übergeben wird, enthält die erwarteten Daten, aber ich muss die Observable ändern. Wie mache ich das?Knockout Wie setze ich Wert in Kind Observable

var MyViewModel = function (data) { 
 
    var self = this; 
 

 
    self.managingAgentId = ko.observable(data.managingAgentId); 
 
    self.companyName = ko.observable(data.companyName); 
 
    self.companyNumber = ko.observable(data.companyNumber); 
 
    self.isActive = ko.observable(data.isActive); 
 
    self.agents = ko.observableArray(data.agents); 
 
    
 
    // Change to Edit or Display mode 
 
    self.changeMode = function (data,event) { 
 
     event.preventDefault(); 
 
     // => need to change mode here! 
 
    }; 
 
} 
 

 

 
$(function() { 
 

 
     $.ajax({ 
 
      type: "GET", 
 
      url: ma.Urls.LoadManagingAgent 
 
     }).done(function (result) { 
 
      $.each(result.agents, function (index, element) { 
 
       element.mode = "display"; 
 
      }); 
 
      
 
      ko.applyBindings(new MyViewModel(result)); 
 
     }).error(function (response) { 
 
      addMessage(response); 
 
     }); 
 
    });
<script type="text/html" id="display"> 
 
    <td data-bind="text: managingAgentMemberId"></td> 
 
    <td data-bind="text: applicationUser.userName"></td> 
 
    <td data-bind="text: applicationUser.email"></td> 
 
    <td data-bind="text: applicationUser.emailConfirmed"></td> 
 
    <td data-bind="text: isActive"></td> 
 
    <td> 
 
     <button class="btn btn-success btn-sm" data-bind="click:$root.changeMode"> 
 
      <i class="fa fa-edit"></i> 
 
      Edit 
 
     </button> 
 
    </td> 
 
</script>

<script type="text/html" id="edit"> 
 
    <td data-bind="text: managingAgentMemberId"></td> 
 
    <td data-bind="text: applicationUser.userName"></td> 
 
    <td data-bind="text: applicationUser.email"></td> 
 
    <td data-bind="text: applicationUser.emailConfirmed"></td> 
 
    <td><input type="checkbox" data-bind="checked: isActive" /> </td> 
 
    <td> 
 
     <button class="btn btn-success btn-sm kout-update"> 
 
      <i class="fa fa-save"></i> 
 
      Update 
 
     </button> 
 
     <button class="btn btn-danger btn-sm kout-cancel"> 
 
      <i class="fa fa-stop"></i> 
 
      Cancel 
 
     </button> 
 
    </td> 
 
</script>

enter image description here

+0

nicht sicher, ich verstehe, was du meinst. applyBindings wird auf dem zurückgegebenen Ajax aufgerufen? – Greg

+0

Ich habe den Kommentar ca 5 Sekunden nach dem Schreiben gelöscht, es scheint etwas Verzögerung zu geben, bis Sie das Löschen sehen. – Tomalak

+0

Worauf möchten Sie den 'Modus' ändern? Auch "Mode" ist nicht einmal in Ihrem Viewmodel beobachtbar. – Tomalak

Antwort

1

Canonical Lösung:

function Child(data) { 
 
    var self = this; 
 
    self.name = ko.observable(); 
 
    self.mode = ko.observable('display'); 
 
    ko.mapping.fromJS(data, Child.mapping, self); 
 
} 
 
Child.prototype.toggleMode = function() { 
 
    this.mode(this.mode() === 'display' ? 'edit' : 'display'); 
 
}; 
 
Child.mapping = { 
 
    // mapping rules, if applicable 
 
}; 
 
function Parent(data) { 
 
    var self = this; 
 
    self.children = ko.observableArray(); 
 
    ko.mapping.fromJS(data, Parent.mapping, self); 
 
} 
 
Parent.mapping = { 
 
    children: { 
 
     create: function (options) { 
 
      return new Child(options.data); 
 
     } 
 
    } 
 
}; 
 

 
ko.applyBindings(new Parent({ 
 
    children: [ 
 
     {name: 'Child 1'}, {name: 'Child 2'}, {name: 'Child 3'} 
 
    ] 
 
}));
td:first-child { 
 
    width: 200px; 
 
} 
 
button { 
 
    width: 6em; 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.min.js"></script> 
 

 
<table> 
 
    <tbody data-bind="foreach: children"> 
 
     <tr data-bind="template: mode"></tr> 
 
    </tbody> 
 
</table> 
 

 
<script type="text/html" id="display"> 
 
    <td data-bind="text: name"></td> 
 
    <td> 
 
     <button data-bind="click: toggleMode">Edit</button> 
 
    </td> 
 
</script> 
 

 
<script type="text/html" id="edit"> 
 
    <td><input data-bind="value: name"></td> 
 
    <td> 
 
     <button data-bind="click: toggleMode">Save</button> 
 
    </td> 
 
</script>

+0

Danke für die Hilfe – Greg

+0

Akzeptieren, aber keine Verbesserung? Nicht dass ich darauf angewiesen wäre, aber ich frage mich, was das für eine Begründung ist. – Tomalak

+0

nur versuchen, Ihre Logik in mein Szenario zu stecken - jetzt upvoting – Greg