【问题标题】:Observable Array Value Update可观察数组值更新
【发布时间】:2016-11-26 03:43:04
【问题描述】:

对于时间表应用程序,我有一个可观察的数组:

日小时

DayHrs 包含 5 天或 7 天,具体取决于员工。 我有一个总 WeekHrs,这是一个计算字段。

当用户输入一个 DayHrs 的值时,我希望 Total WeekHrs 字段立即更新。

所以在我的数据绑定中,我想使用 valueUpdate: 'afterkeydown'。

但是我不能将其设为计算字段,因为可观察数组中的数组项本身不是可观察的。

根据 Knockout 文档:关键点:一个 observableArray 跟踪数组中的哪些对象,而不是这些对象的状态。

那么我该如何解决这个问题?有没有办法遍历数组以使每个项目都可观察(我还没有看到如何做到这一点)或者我应该指定一个更改事件?还是别的什么?

【问题讨论】:

    标签: arrays knockout.js


    【解决方案1】:

    有两种主要方法可以将“普通 javascript 对象”转换为具有可观察属性的视图模型:

    1. 自动,通过ko.mapping.fromJS,或
    2. 手动。

    如果您想使用选项 2,我会给出答案。如果您想自动执行 (1),最好查看文档和示例 here

    在下面的代码中,我编写了一个将纯 javascript 对象和数组转换为 ko.observableko.observableArray 属性的示例。每个视图模型都有一个构造函数或静态create 方法,它“知道”如何处理指定的数据格式。对于数据中的每个属性,您可以选择:

    1. 忽略它(当它不在视图中呈现时,它在您的视图模型中不起作用)
    2. 使其成为常规属性(当它在您的视图中静态呈现时)
    3. 使其可观察(当它需要在视图中更新时)

    然后,您可以添加ko.computed 属性和方法以使您的视图具有交互性。

    var Day = function(initialHours) {
      this.hours = ko.observable(initialHours || 0);
    };
    
    Day.create = function(data) {
      return new Day(data.Hours);  
    }
    
    var Week = function(initialDays) {
      this.days = ko.observableArray(initialDays.map(Day.create));
      
      this.totalHours = ko.pureComputed(function() {
        return this.days().reduce(function(sum, day) {
          return sum + parseInt(day.hours(), 10);
        }, 0);
      }, this);
    };
        
    Week.create = function(dayArray) {
      return new Week(dayArray);
    };
    
    var Employee = function(employeeData) {
      this.name = employeeData.Name;
      this.workWeek = Week.create(employeeData.WorkWeek);
    };
    
    Employee.create = function(employeeData) {
      return new Employee(employeeData);
    };
    
    var testData = [{
      Name: "John Doe",
      WorkWeek: [
        { Hours: 4 },
        { Hours: 8 },
        { Hours: 8 },
        { Hours: 8 },
        { Hours: 6 }
      ]
    }];
      
    var vm = {
      employees: testData.map(Employee.create)
    };
    
    ko.applyBindings(vm);
    input[type="number"] { width: 30px }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
    
    
    <ul data-bind="foreach: employees">
      <li>
        <div data-bind="text: name"></div>
        <div data-bind="with: workWeek">
          <!-- ko foreach: days -->
          <input data-bind="value: hours" type="number"/> -
          <!-- /ko -->
          <span data-bind="text: 'total: ' + totalHours()"></span>
        </div>
      </li>
    </ul>

    【讨论】:

      猜你喜欢
      • 2012-06-30
      • 2018-07-27
      • 2021-10-26
      • 2013-12-16
      • 2020-11-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-12
      相关资源
      最近更新 更多