2012-04-12 4 views
1

Siehe Code entfernen können (bin mit Knockout.js über ASP MVC 3):Knockout.js - nicht Länge von Array bekommen nicht Gegenstand von Array

@model List<Person> 
@{ 
    ViewBag.Title = "Home Page"; 
} 
<table> 
    <thead><tr> 
     <th>First Name</th><th>Last Name</th><th>Age</th><th>Department</th> <th></th> 
    </tr></thead> 
    <tbody data-bind="foreach: people"> 
    <tr> 
     <td><input data-bind="value: FirstName" /></td> 
     <td><input data-bind="value: LastName"></select></td> 
     <td><input data-bind="value: Age"></select></td> 
     <td><select></select></td> 
     <td><a href="#" data-bind="click: $root.removePerson">Remove</a></td> 
    </tr>  
    </tbody> 
    <tfoot> 
     <tr> <th align=left colspan=4>Total number of people:</th> <th><span data-bind="text: $root.people().length"></span></th> </tr> 
    </tfoot> 

</table> 

<button data-bind="click: addPerson, enable: people().length < 5">Add another person</button> 

<script type="text/javascript"> 
    function ViewModel() { 
     var self = this; 
     self.people = ko.observableArray(ko.mapping.fromJS(@Html.Raw(new JavaScriptSerializer().Serialize(Model)))); 

     self.addPerson = function() { 
      self.people.push(@Html.Raw(new JavaScriptSerializer().Serialize(new Person() { FirstName = "I am", LastName = "a new Person", Age = "0" }))); 
     } 

     self.removePerson = function(person) 
     { 
      self.people.remove(person) 
     } 
    } 

    ko.applyBindings(new ViewModel()); 
</script> 

public class Person 
{ 
    public string FirstName { get; set; } 

    public string LastName { get; set; } 

    public string Age { get; set; } 

    public string FullName 
    { 
     get { return FirstName + " " + LastName; } 
    } 
} 

Meine Fragen ist, warum die Menschen bedeutet() Länge Rückkehr. 0? (Warum kann ich ein Element aus dem Array mit meiner Funktion removePerson nicht entfernen?) -> gelöst

EDIT: Hier ist das HTML erzeugt Homepage

<script src="/Scripts/knockout.js" type="text/javascript"></script> 
    <script src="/Scripts/knockout.mapping-latest.js" type="text/javascript"></script> 
</head> 
<body> 
    <div class="page"> 
     <div id="header"> 
      <div id="title"> 
       <h1> 
        My MVC Application</h1> 
      </div> 
      <div id="logindisplay"> 
        [ <a href="/Account/LogOn">Log On</a> ] 

      </div> 
      <div id="menucontainer"> 
       <ul id="menu"> 
        <li><a href="/">Home</a></li> 
        <li><a href="/Home/About">About</a></li> 
       </ul> 
      </div> 
     </div> 
     <div id="main"> 
      <table> 
    <thead><tr> 
     <th>First Name</th><th>Last Name</th><th>Age</th><th>Department</th> <th></th> 
    </tr></thead> 
    <tbody data-bind="foreach: people"> 
    <tr> 
     <td><input data-bind="value: FirstName" /></td> 
     <td><input data-bind="value: LastName"></select></td> 
     <td><input data-bind="value: Age"></select></td> 
     <td><select></select></td> 
     <td><a href="#" data-bind="click: $root.removePerson">Remove</a></td> 
    </tr>  
    </tbody> 
    <tfoot> 
     <tr> <th align=left colspan=4>Total number of people:</th> <th><span data-bind="text: $root.people().length"></span></th> </tr> 
    </tfoot> 

</table> 

<button data-bind="click: addPerson, enable: people().length < 5">Add another person</button> 

<script type="text/javascript"> 
    function ViewModel() { 
     var self = this; 
     self.people = ko.observableArray(ko.mapping.fromJS([{"FirstName":"Basti","LastName":"Wuf","Age":"28","FullName":"Basti Wuf"},{"FirstName":"Mawie","LastName":"Mew","Age":"25","FullName":"Mawie Mew"}])); 

     self.addPerson = function() { 
      self.people.push({"FirstName":"I am","LastName":"a new Person","Age":"0","FullName":"I am a new Person"}); 
     } 

     self.removePerson = function(person) 
     { 
      //alert(person.FirstName); 
      self.people.remove(person) 
     } 
    } 

    ko.applyBindings(new ViewModel()); 
</script> 

     </div> 
     <div id="footer"> 
     </div> 
    </div> 
</body> 
</html> 
+0

Bitte verwenden Sie das generierte HTML. – SLaks

+0

fertig! Frage aktualisiert! :) –

Antwort

2

ko.mapping.fromJS wenn gegeben ein Array macht es zu einem ObservableArray.

Also, wenn Sie das tun:

self.people = ko.observableArray(ko.mapping.fromJS([{"FirstName":"Basti","LastName":"Wuf","Age":"28","FullName":"Basti Wuf"},{"FirstName":"Mawie","LastName":"Mew","Age":"25","FullName":"Mawie Mew"}]));

self.people gewickelt wird zweimal (observableArray enthält eine observableArray).

Also würde self.people() das innere ObservableArray zurückgeben. Eine length darauf (eine Funktion) wird die Anzahl der Argumente für die Funktion (in diesem Fall 0) zurückgegeben.

Grundsätzlich können Sie nur die äußere ko.observableArray im View-Modell-Initialisierungscode entfernen und das Mapping-Plugin für Sie tun lassen.

+0

danke! das hat es getan! :) self.people = ko.mapping.fromJS (@ Html.Raw (neuer JavaScriptSerializer(). Serialize (Modell))); –

+0

eine Frage jedoch, wie hat die Tabelle das gesamte Element dann, wenn die Elemente ein Array innerhalb eines Arrays sind? (Da alles, was ich tat war Datenbindung = "foreach: people" und immer noch die Tabelle wurde generiert) –

+0

Es ist ein Zufall, dass es richtig funktioniert. Die "foreach" -Bindung wickelt sie einmal aus, bevor sie sie an die "Schablonen" -Bindung übergibt, und die "Schablonen" -Bindung führt die zweite Entpackung durch. –