2017-08-10 69 views
1

我正尝试使用基因敲除来创建一个简单的电子表格。我试图让每个细胞都是可观察的,所以在变化时,我可以评估这些值并据此进行计算。因此,如果他们在一个单元格中输入6 + 7,我可以评估并将其值更改为总数。阵列内的基因敲除阵列

但是,我不能让每个单元格都是可观察的。也许我错了。

我试图创建一个小提琴,但我现在正在争取让jquery加载。所以尽管我可以在本地的Visual Studio中运行它,但小提琴抱怨着$。 (任何帮助解决这将是伟大的)。

http://jsfiddle.net/tr9asadp/1/

我生成这样我的可观察到的数组: self.RowCount = ko.observable(0); self.ColumnCount = ko.observable(0);

self.Columns = ko.observableArray([]); 
self.Rows = ko.observableArray([]); 

self.Refresh = function() { 

    for (i = 0; i < self.RowCount(); i++) { 
     var obj = { 
      data: i + 1, 
      calculated: i, 
      rowNum: i, 
      colNum: 0, 
      columns: ko.observableArray([]) 
     }; 

     for (j = 0; j < self.ColumnCount(); j++) { 
      obj.columns.push(ko.observable({ 
       label: self.Letters[j], 
       value: j + 1, 
       colIndex: j, 
       rowIndex: i 
      })); 
     } 
     self.Rows.push(obj); 

    } 
    self.ShowSheet(self.RowCount() > 0 && self.ColumnCount() > 0); 

我呈现基于列和由用户输入(目前行的表,限于5×5,如我使用阵列转换1,2,3(列),以A,B ,C,但这是暂时的,将是固定的。

我怎样才能得到每个单元可观察到,这样我就可以订阅并触发对变化的事件?

回答

1

你似乎并不具备利用了cellObject(从你的小提琴)。如果你添加cellObject类型的对象到行中,并且在那里有一个可观察的value,你可以订阅chang就此而言。

固定码:

var cellObject = function() { 
 
    var self = this; 
 
    self.data = ko.observable(); 
 
    self.calculated = ko.observable(); 
 
    self.rowNum = ko.observable(0); 
 
    self.colNum = ko.observable(0); 
 
    self.rows = ko.observableArray([]); 
 
    self.value = ko.observable(); 
 
} 
 

 
function SpreadsheetViewModel() { 
 
    var self = this; 
 
    self.ShowSheet = ko.observable(false); 
 
    self.ShowSheet(false); 
 

 
    self.Letters = ['A', 'B', 'C', 'D', 'E'] 
 

 

 
    self.RowCount = ko.observable(0); 
 
    self.ColumnCount = ko.observable(0); 
 

 
    self.Columns = ko.observableArray([]); 
 
    self.Rows = ko.observableArray([]); 
 

 
    function valueChanged(newValue) { 
 
    console.log("Value changed to " + newValue); 
 
    } 
 

 
    self.Refresh = function() { 
 

 
    for (i = 0; i < self.RowCount(); i++) { 
 
     var row = { 
 
     cells: ko.observableArray([]) 
 
     }; 
 

 
     for (j = 0; j < self.ColumnCount(); j++) { 
 
     var cell = new cellObject(); 
 
     cell.label = self.Letters[j]; 
 
     cell.data(i + 1); 
 
     cell.calculated(i); 
 
     cell.rowNum(i); 
 
     cell.colNum(j); 
 
     cell.value(j + 1); 
 

 
     cell.value.subscribe(valueChanged); 
 
     row.cells.push(cell); 
 
     } 
 
     self.Rows.push(row); 
 

 
    } 
 
    self.ShowSheet(self.RowCount() > 0 && self.ColumnCount() > 0); 
 
    } 
 

 
    self.Refresh(); 
 

 
} 
 

 
var vm = new SpreadsheetViewModel(); 
 
ko.applyBindings(vm);
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" /> 
 
<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.4.2/knockout-min.js"></script> 
 
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> 
 

 
<div id="spreadsheetSection"> 
 

 
    <div class="row"> 
 
    <div class="col-xs-3 text-right">No. of Columns</div> 
 
    <div class="col-xs-2"> 
 
     <input type="text" class="form-control" placeholder="Columns" data-bind="value: ColumnCount"> 
 
    </div> 
 
    <div class="col-xs-3 text-right">No. of Rows</div> 
 
    <div class="col-xs-2"> 
 
     <input type="text" class="form-control" placeholder="Rows" data-bind="value: RowCount"> 
 
    </div> 
 
    <div class="col-xs-2"> 
 
     <button class="btn btn-default" data-bind="click: Refresh">Refresh</button> 
 
    </div> 
 
    </div> 
 
    <div class="row"> 
 
    <!-- ko if: ShowSheet --> 
 
    <table class="table table-bordered table-hover table-striped"> 
 
     <tbody> 
 
     <tr data-bind="foreach: Rows()[0].cells"> 
 
      <td> 
 
      <span data-bind="text: label"></span> 
 
      </td> 
 

 
     </tr> 
 
     </tbody> 
 
     <tbody data-bind="foreach: Rows"> 
 
     <tr data-bind="foreach: cells"> 
 
      <td> 
 
      <input type="text" class="form-control" data-bind="value: value"> 
 
      </td> 
 
     </tr> 
 
     </tbody> 
 
    </table> 
 
    <!-- /ko --> 
 
    </div> 
 
</div>

固定小提琴:https://jsfiddle.net/tr9asadp/3/

+0

谢谢!这很好。我太亲密了...只是没有让我的头在使用我的对象,而不是一个匿名的。我最喜欢订阅主视图模型吗?原因是,如果该人输入'= B2'...我需要找到B2单元格,获取该值并使用该值。在对象中订阅它是自我的 - 我不确定我可以访问所有其他单元格。 – Craig

+0

检查更新。它并不是完全订阅到主视图模型,但该功能现在位于主视图模型中,因此您可以访问其他单元格。 – H77

+0

谢谢H77 ...我得到'valueChanged'不是一个函数。应该将其声明为self.valueChanged吗? – Craig

0

我使用的writableComputable http://knockoutjs.com/documentation/computed-writable.html,使得如果在细胞和标签出的一种类型的1 + 1,它会更改为2.这里是更新的小提琴。 http://jsfiddle.net/tr9asadp/5/

function column(label, value, colIndex, rowIndex){ 
var self = this; 
this.label = ko.observable(label); 
this.value = ko.observable(value); 
this.colIndex = ko.observable(colIndex); 
this.rowIndex = ko.observable(rowIndex); 
this.writableValue = ko.pureComputed({ 
     read: function() { 
      return self.value(); 
     }, 
     write: function (v) { 
      self.value(eval(v)) 
     }, 
     owner: this 
    }); 
}