2017-01-10 67 views
0

我剛從Knockout開始並運行一個多站點課程。 我對基於父陣列的計算財產(大概基本的)問題:基於外部陣列的計算屬性Knockout JS

考慮下面的代碼我怎麼讓它工作,使Amount屬性在my.vm.attendees每個項目始終是totalCost除以數的與會者。例如。 4名參加者的收款金額應爲25. 這應在您添加和移除項目時自動更新。

<script type="text/javascript"> 
    $(function() { 
     var total = 100; 

     //Attendee construction 
     my.Attendee = function() { 
      this.Name = ko.observable(); 
      this.Amount = ko.computed(function() { 
       return total/this.numberOfAttendees; 
      }, my.vm); 
     }; 

     my.vm = { 
      //observable array of attendees 
      attendees: ko.observableArray([new my.Attendee()]), 
      addAttendee: function() { 
       my.vm.attendees.push(new my.Attendee()); 
      }, 
      numberOfAttendees: function() { 
       my.vm.attendees.lenght + 1; //zero based 
      } 
     } 

     ko.applyBindings(my.vm); 
    }); 
</script> 

回答

1

我可能會這樣做。

function attendee(name, amount) { 
 
    var self = this; 
 
    this.name = ko.observable(name); 
 
    this.amount = ko.observable(amount); 
 
} 
 

 
function model() { 
 
    var self = this; 
 
    this.attendees = ko.observableArray(); 
 
    this.total = ko.computed(function() { 
 
    var total = 0; 
 
    ko.utils.arrayForEach(this.attendees(), function(item) { 
 
     var value = parseFloat(item.amount()); 
 
     if (!isNaN(value)) { 
 
     total += value; 
 
     } 
 
    }); 
 
    return total.toFixed(2); 
 
    }, this); 
 
    this.average = ko.pureComputed(function() { 
 
    return self.total()/self.attendees().length; 
 
    }, this); 
 
    this.remove = function(row) { 
 
    self.attendees.remove(row); 
 
    } 
 
    this.name = ko.observable(''); 
 
    this.amount = ko.observable(''); 
 
    this.add = function() { 
 
    self.attendees.push(new attendee(self.name(), self.amount())); 
 
    self.amount(''); 
 
    self.name(''); 
 
    } 
 
} 
 

 
var mymodel = new model(); 
 

 
$(document).ready(function() { 
 
    ko.applyBindings(mymodel); 
 
    mymodel.attendees.push(new attendee('Bob', 25)); 
 

 
});
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 
 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<table class="table table-condensed"> 
 
    <thead> 
 
    <tr> 
 
     <th>Name</th> 
 
     <th>Amount</th> 
 
     <td>Delete</td> 
 
    </tr> 
 
    </thead> 
 
    <tbody data-bind="foreach: attendees"> 
 
    <tr> 
 
     <td data-bind="text:name"></td> 
 
     <td data-bind="text:amount"></td> 
 
     <td> 
 
     <button class="btn btn-danger" data-bind="click: $parent.remove"> 
 
      X 
 
     </button> 
 
     </td> 
 
    </tr> 
 
    </tbody> 
 
    <tfooter> 
 
    <tr> 
 
     <td colspan=2>Average: 
 
     <span data-bind="text:average"> 
 
     </span> 
 
     </td> 
 
    </tr> 
 
    </tfooter> 
 
</table> 
 

 
<form class="form form-inline"> 
 
    <label class="sr-only" for="inlineFormInput">Name</label> 
 
    <input type="text" class="form-control" id="inlineFormInput" placeholder="enter name" data-bind="textInput: name"> 
 

 
    <label class="sr-only" for="inlineFormInputGroup">Amount</label> 
 
    <div class="input-group "> 
 
    <div class="input-group-addon">$</div> 
 
    <input type="text" class="form-control" id="inlineFormInputGroup" placeholder="amount" data-bind="textInput: amount"> 
 
    </div> 
 

 

 
    <button type="buttont" class="btn btn-primary" data-bind="click: add">add row </button> 
 
</form>

0

無論何時更新任何兒童可觀察量,計算的「金額」將被重新計算。因此,如果您希望觸發更改,則需要使「總計」爲可觀察值,並且您需要使「numberOfAttendees」自身計算,以便在my.vm.attendees更新時更新它,以及可以級聯到計算的「金額」的更新。