【问题标题】:Sending only the updated object from ko.observableArray仅从 ko.observableArray 发送更新的对象
【发布时间】:2025-12-13 12:00:01
【问题描述】:

如何仅发送可观察数组中的更新模型,而不是发送整个数组?

var student = function (){
    this.studentId=0;
    this.firstName=ko.obserable();
    this.lastName=ko.obserable();
}
var course= function (){
    this.courseId=0;
    this.students=ko.obserableArray([]);
    this.Name=ko.obserable();
}

现在我只想从课程中获取信息已更新的特定学生。假设当我们添加一个新班级时,我们可以在旅途中动态地向其中添加新学生。假设您必须在添加新学生之前验证前一个学生。当我得到那个特定的学生时,我想将该学生信息发送回服务器。

谢谢。

【问题讨论】:

  • 在添加新学生之前验证之前的学生是什么意思?
  • 我有一个(添加更多)按钮,可以将新学生添加到 DOM 和数据库中。验证意味着如果用户输入了学生的有效信息,那么他可以将另一个学生添加到该课程中。
  • 我发布了关于如何获取已修改学生列表的答案。

标签: javascript mvvm knockout.js knockout-validation knockout-3.0


【解决方案1】:

如果我理解您的任务,您可以使用“arrayChange”事件类型来获取完全更改(添加/删除)的项目:

sourceArray = ko.observableArray();
sourceArray.subscribe(function (changes) {
        changes.forEach(function(arrayChange) {
            if(arrayChange.status === 'added') {
                // some code on add
            } else if(arrayChange.status === 'deleted') {
                // some code on delete
            }
        });
    }, null, "arrayChange");

【讨论】:

    【解决方案2】:

    如果您想获取已修改的学生列表,您可以提供一个标志来标识学生对象中的对象是否已被修改。每当更新值时,使用.subscribe 修改该标志。然后使用ko.computedko.pureComputed 获取该列表。

    也应该是observable

    var student = function (id, firstName, lastName) {
      var self = this;
      self.hasChanged = ko.observable(false);
      var modified = function(){
        self.hasChanged(true);
      };
    
      self.studentId = ko.observable(id);
      self.firstName = ko.observable(firstName);
      self.firstName.subscribe(modified);
      self.lastName = ko.observable(lastName);
      self.lastName.subscribe(modified);
    }
    var course= function (){
      var self = this;
      self.courseId = 0;
      self.students = ko.observableArray([new student(1, "Cristiano", "Ronaldo"), new student(2, "Lionel", "Messi")]);
      self.modifiedStudent = ko.computed(function(){
        return ko.utils.arrayFilter(self.students(), function(student) {
            return student.hasChanged();
        });
      }, self);
      self.Name = ko.observable("Programming 101");
    }  
    
    $(document).ready(function () {
      var myViewModel = new course();
      ko.applyBindings(myViewModel);
    });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
    
    List of all students:
    <div data-bind="foreach: students">
      <div>
        <span data-bind="text: studentId"></span>
        <input type="text" data-bind="value: firstName" />
        <input type="text" data-bind="value: lastName" />
      </div>
    </div>
    <br/>
    
    List of students which has been modified:
    <div data-bind="foreach: modifiedStudent">
      <div>
        <span data-bind="text: studentId"></span>
        <input type="text" data-bind="value: firstName" readonly />
        <input type="text" data-bind="value: lastName" readonly />
      </div>
    </div>

    【讨论】: