Search code examples
asp.net-mvcknockout.jsasp.net-core-mvcknockout-3.0

knockout.js ul li databinding not proper


HTML

<h4>People</h4>
<ul data-bind="foreach: people">
    <li>      
        <span data-bind="text: name"> </span>
        <a href="#" data-bind="click: $parent.removePerson">Remove</a>
    </li>
</ul>
<button data-bind="click: addPerson">Add</button>                      
<input type="text" data-bind="value: cardtext" /><br /><br /><br />

JS

function AppViewModel() {
    var self = this;
    self.cardtext=ko.observable();


   self.people = ko.observableArray([
       { name: 'Bert' },
       { name: 'Charles' },
       { name: 'Denise' }
   ]);

   self.addPerson = function() {
      self.people.push({ name: self.cardtext });
   };

   self.removePerson = function() {
      self.people.remove(this);
   }
}     
ko.applyBindings(new AppViewModel());

This is the result

enter image description here

The problem is that the textbox keep adding new elements but the previous newly added elements keep getting updated by the new elements.

3rd element was 3rd element

4th element was 4th element

when I added 5th element the 3rd and the 4th element get updated by 5th element.
why it is that? what I am doing wrong?. I have no idea.


Solution

  • You just need to add () at the end of self.cardtext(). If you don't put the parenthesis, what it will do is it will push the observable object of cardtext to the array instead of its value. So when you modify cardtext from the textbox, it will also modify the previous object that was pushed.

       
    function AppViewModel() {
      var self = this;
      self.cardtext=ko.observable();
      self.people = ko.observableArray([
        { name: 'Bert' },
        { name: 'Charles' },
        { name: 'Denise' }
      ]);
    
      self.addPerson = function() {
        self.people.push({ name: self.cardtext() });
      };
    
      self.removePerson = function() {
        self.people.remove(this);
      }
    }     
    ko.applyBindings(new AppViewModel());
    <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>
    
    <h4>People</h4>
    <ul data-bind="foreach: people">
      <li>      
        <span data-bind="text: name"> </span>
        <a href="#" data-bind="click: $parent.removePerson">Remove</a>
      </li>
    </ul>
    <button data-bind="click: addPerson">Add</button>                      
    <input type="text" data-bind="value: cardtext" /><br /><br /><br />