Search code examples
javascriptknockout.jsknockout-2.0knockout-3.0

How to carry one viewModel data to other ViewModel function using Knockout JS of another page


I am using the Knockout js in my single page Application,I need to carry the value of one viewmodel data to another viewModel data,So i can reduce my duplication creating same view, How i can achieve this below is my code.I got 2 different js file,which one consist of Employee ViewModel and in another Department View Model

      //Employee View
       <div class="Employee-view"  data-role="view" id="employee">
         <div data-role="content" >
           <ul>
             <li foreach:EmployeeData>
              //Onlcick of this need to navigate to  Department view and bind all values on particular Employee ID 
              <div databind:"click:GetDepartmentDetails">
                <span data-bind:"text:EmployeeId"> <span>
                <span data-bind:"text:EmployeeName"> <span>
                <span data-bind:"text:EmployeeImage"> <span>
             <div> 
            <li>
          <ul>
        </div>
       </div>


     EmployeeViewModel = new EmployeeDetailsViewModel();;
     $(".Employee-view").each(function () {
        ko.applyBindings(EmployeeViewModel, $(this).get(0));
     });


     function EmployeeViewModel(){
        var self=this;
        self.EmployeeData = ko.observableArray([]);
        self.GetEmployee = function(UserName,Password){  
           var UserModel = { UserName: UserName, Password: Password}
           $.ajax({
                type: "POST",
                dataType: "json",
                url: serverUrl + 'xxx/xxx/GetEmployee',
                data: UserModel,
                success: function (data) {
                   self.EmployeeData($.map(data, function (item) {
                     return new EmployeeModel(item);
                   }))
                }
           });
         }

        //Click EVENT
        self.GetDepartmentDetails=(EmployeeData){
          // I am getting all the value in this ViewModel,I need to pass   this value to DepartmentViewModel  and i need to call the function  
          self.GetEmployeeByDepartment();
        }

     }

     function EmployeeModel(data)
     {
       var self = this;
       self.EmployeeId = ko.observable(data.EmployeeId)
       self.EmployeeName = ko.observable(data.EmployeeName)
       self.EmployeeImage = ko.observable(data.EmployeeImage)
      }

       //Department View
       <div class="Department-view" data-role="view" id="Department">
         <div data-role="content">
           <ul>
             <li   data-bind:"foreach:DepartmentData ">
              <div>
                <span data-bind:"text:DeptId"> <span>
                <span data-bind:"text:DeptName"> <span>
              </div> 
             </li>
           </ul>
         </div>
       </div>

      //Department View Model
      function DepartmentViewModel ()
      {
        var self = this;
        self.DepartmentData = ko.observableArray([]);
        self.GetEmployeeByDepartment = function(item){  
          employeeID = item.EmployeeId
          employeename = item.Employeename
          var DeptModel = { Employeename: employeeID, Employeename: employeename}
          $.ajax({
            type: "POST",
            dataType: "json",
            url: serverUrl + 'xxx/xxx/GetDepratmenDetails',
            data: DeptModel ,
            success: function (data) {
               self.DepartmentData ($.map(data, function (item) {
                 return new DepartmentModel(item);
               })),
            });
          }}
       }

       function DepartmentModel(data)
       {
         var self=this;
         self.DeptId = ko.observable(data.DeptID)
         self.DeptName = ko.observable(data.DeptName)
       }

       DepartmentViewModel = new DepartmentDetailsViewModel();
       $(".Department-view").each(function () {
         ko.applyBindings(DepartmentViewModel, $(this).get(0));
       });

Its a duplicate question as we were not able to fix it. Please help How to carry the data from one viewModel to another ViewModel Knockout JS


Solution

  • First there are many typos and wrong bindings in your view that need your attention. Example :

    <ul>
      <li foreach:EmployeeData>  // There is no data-bind="
        <div databind:"click:GetDepartmentDetails">   //databind => data-bind and You need = not : <div data-bind="click:$parent.GetDepartmentDetails">
            <span data-bind:"text:EmployeeId"> <span> // You need = not : 
            <span data-bind:"text:EmployeeName"> <span>
            <span data-bind:"text:EmployeeImage"> <span>
         <div> 
       <li>
    <ul>
    

    You can define an observable variable in your employeeViewModel to hold a new instance of DepartmentViewModel and then you can call any functions through that variable and there is no need to re-apply ko many times.

    Below I am trying to use your code by using a fake data to show you how you can approach this. Example : https://jsfiddle.net/kyr6w2x3/157/

    View:

    <h1>Employee View</h1>
    <div class="Employee-view"  data-role="view" id="employee">
      <div data-role="content" >
        <ul>
          <li data-bind="foreach:EmployeeData">
            <div data-bind="click:$parent.GetDepartmentDetails">
              <span data-bind="text:EmployeeId"> </span>
              <span data-bind="text:EmployeeName"> </span>
              <span data-bind="text:EmployeeImage"> </span>
            </div> 
          </li>
        </ul>
      </div>
    </div>
    
    <hr>
    
    <h1>Department View</h1>
    <div data-bind="with:DepartmentVM">
      <div class="Department-view" data-role="view" id="Department">
        <div data-role="content">
          <ul>
            <li   data-bind = "foreach:DepartmentData ">
              <div>
                <span data-bind = "text:DeptId"> </span>
                <span data-bind = "text:DeptName"> </span>
              </div> 
            </li>
          </ul>
        </div>
      </div>
    </div>
    

    Models :

    function EmployeeViewModel() {
      var self = this;
      // Here you define an observable variable to hold your DepartmentVM 
      self.DepartmentVM = ko.observable();
      self.EmployeeData = ko.observableArray([]);
      self.GetEmployee = function(UserName,Password){  
        var UserModel = { UserName: UserName, Password: Password}
        $.ajax({
           type: "POST",
           dataType: "json",
           url: serverUrl + 'xxx/xxx/GetEmployee',
           data: UserModel,
           success: function (data) {
             self.EmployeeData($.map(data, function (item) {
               return new EmployeeModel(item);
             }))
           }
        });
      }
    
      //Here I am calling GetEmployee()
      self.GetEmployee();
    
      // Below you have a knockout function
      self.GetDepartmentDetails = function (EmployeeData){
        console.log(EmployeeData)
        // Create a new instance of your DepartmentViewModel and then you can call the fucntion inside of it and pass your data
        self.DepartmentVM(new DepartmentViewModel());
        self.DepartmentVM().GetEmployeeByDepartment(EmployeeData);
      }
    }
    function DepartmentViewModel () {
      var self = this;
      self.DepartmentData = ko.observableArray([]);
      self.GetEmployeeByDepartment = function(item){  
        //Below you need ()  to get the value of observable variable item.EmployeeId()
        employeeID = item.EmployeeId()
        employeename = item.EmployeeName()  
    
         var DeptModel = { Employeename: employeeID, Employeename: employeename}
         $.ajax({
           type: "POST",
           dataType: "json",
           url: serverUrl + 'xxx/xxx/GetDepratmenDetails',
           data: DeptModel ,
           success: function (data) {
              self.DepartmentData ($.map(data, function (item) {
                 return new DepartmentModel(item);
               }))
           }
        });
      }
    }
    
    function DepartmentModel(data)
    {
      var self = this;
      self.DeptId = ko.observable(data.DeptID)
      self.DeptName = ko.observable(data.DeptName)
    }
    function EmployeeModel(data)
    {
      var self = this;
      self.EmployeeId = ko.observable(data.EmployeeId)
      self.EmployeeName = ko.observable(data.EmployeeName)
      self.EmployeeImage = ko.observable(data.EmployeeImage)
    }
    var EmployeeVM = new EmployeeViewModel()
    ko.applyBindings(EmployeeVM);