1

I have the below code and I'm confused why is the second alert displaying the first view model (vm1) instead of the second one (vm2)?

<div id="main">
    <div data-bind="testBinding: vm1"></div>
    <div data-bind="testBinding: vm2"></div>
</div>

<script>
    function vm1() {
        this.firstName = "test first name"
    }

    function vm2() {
        this.lastName = 'test last name';
    }

    ko.bindingHandlers.testBinding = {
        init: function(element, valueAccessor, allBindings, viewModel, 
              bindingContext) {

              alert(JSON.stringify(bindingContext.$data))
        },
   };

   ko.applyBindings(new vm1(), document.getElementById('main'));
</script>
user3587180
  • 1,317
  • 11
  • 23
  • Because you create the viewmodel from vm1 `new vm1()` when applying the bindings. – muhihsan May 20 '17 at 03:51
  • @M.Ihsan Shouldn't that not matter because I'm looking for all the bindings inside the main div right? http://stackoverflow.com/questions/18990244/whats-the-applybindings-second-parameter-used-for – user3587180 May 20 '17 at 03:58
  • Exactly, you're looking at all the bindings inside the main div. But you didn't bind vm2, which is why you can't see it there. Look at my answer below. – muhihsan May 20 '17 at 10:34

1 Answers1

1

It's showing the first ViewModel (vm1) only because when you apply the binding, you pass viewmodel of the vm1.

ko.applyBindings(new vm1(), document.getElementById('main'));

Also, bindingContext parameter from ko.bindingHandlers will get you the viewModel that you pass to the ko.applyBinidngs. Since you pass the first viewmodel during the binding, you'll only get that information.

http://knockoutjs.com/documentation/custom-bindings.html

If you want to get both v1 and v2 from the ko.bindingHandlers, you can create another viewmodel and create 2 properties for each of them.

function vm1() {
    this.firstName = "test first name"
}

function vm2() {
    this.lastName = 'test last name';
}

function viewModel() {
  this.vm1 = new vm1();
  this.vm2 = new vm2();
}

ko.bindingHandlers.testBinding = {
    init: function(element, valueAccessor, allBindings, viewModel, 
          bindingContext) {

          alert(JSON.stringify(bindingContext.$data))
    },
};

ko.applyBindings(new viewModel(), document.getElementById('main'));

Then you'll get this result on the alert box

{"vm1":{"firstName":"test first name"},"vm2":{"lastName":"test last name"}}

muhihsan
  • 2,250
  • 6
  • 27
  • 42