admin管理员组

文章数量:1023009

I have getGeneral function that calls ajax GET. When ajax recieves data (json), it creates KO model from given json and returns created KO.

When Knockout model is created and values are assigned, knockout applybindings should be called. Here is my code:

Defines GeneralModel and some related functions (inside "GeneralModel.js"):

var GeneralModel = function() {

   //for now it is empty as data ar binded automatically from json
   // CountryName is one of the properties that is returned with json
} 

function getGeneral(pid) {
    $.ajax({
        url: "/api/general",
        contentType: "text/json",
        dataType: "json",
        type: "GET",
        data: { id: pid},
        success: function (item) {
            var p = new GeneralModel();
            p = ko.mapping.fromJS(item);
            return p;
        },
        error: function (data) {

        }
    });    
}

This is called from another file (GeneralTabl.html), it should call get function and applyBindings to update UI:

var PortfolioGeneral = getGeneral("@Model.Id");
ko.applyBindings(PortfolioGeneral, document.getElementById("pv-portfolio-general-tab"));

However, in this scenario I am getting error (CountryName is not defined). This is because applyBindings happens before ajax returns data, so I am doing applyBindings to empty model with undefined properties.

Mapping from Json to Model happens here and is assignes values: p = ko.mapping.fromJS(item);

I can also fill in GeneralModel with all fields, but it is not necessary (I guess):

  var GeneralModel = function() {    
      CountryName = ko.observable();
      ...
  } 

It will still give an error "CountryName is not defined".

What is the solution?

1) Can I somehow move getGeneral inside GeneralModel, so get data would be part of GeneralModel initialization?

or

2) Maybe I should somehow do "wait for ajax results" and only then applyBindings?

or

I believe there are other options, I am just not so familiar with KO and pure JS.

Note: I fully understand that this is because Ajax is Async call, so the question is how to restructure this code taking into account that I have two seperate files and I need to call getGeneral from outside and it should return some variable.

I have getGeneral function that calls ajax GET. When ajax recieves data (json), it creates KO model from given json and returns created KO.

When Knockout model is created and values are assigned, knockout applybindings should be called. Here is my code:

Defines GeneralModel and some related functions (inside "GeneralModel.js"):

var GeneralModel = function() {

   //for now it is empty as data ar binded automatically from json
   // CountryName is one of the properties that is returned with json
} 

function getGeneral(pid) {
    $.ajax({
        url: "/api/general",
        contentType: "text/json",
        dataType: "json",
        type: "GET",
        data: { id: pid},
        success: function (item) {
            var p = new GeneralModel();
            p = ko.mapping.fromJS(item);
            return p;
        },
        error: function (data) {

        }
    });    
}

This is called from another file (GeneralTabl.html), it should call get function and applyBindings to update UI:

var PortfolioGeneral = getGeneral("@Model.Id");
ko.applyBindings(PortfolioGeneral, document.getElementById("pv-portfolio-general-tab"));

However, in this scenario I am getting error (CountryName is not defined). This is because applyBindings happens before ajax returns data, so I am doing applyBindings to empty model with undefined properties.

Mapping from Json to Model happens here and is assignes values: p = ko.mapping.fromJS(item);

I can also fill in GeneralModel with all fields, but it is not necessary (I guess):

  var GeneralModel = function() {    
      CountryName = ko.observable();
      ...
  } 

It will still give an error "CountryName is not defined".

What is the solution?

1) Can I somehow move getGeneral inside GeneralModel, so get data would be part of GeneralModel initialization?

or

2) Maybe I should somehow do "wait for ajax results" and only then applyBindings?

or

I believe there are other options, I am just not so familiar with KO and pure JS.

Note: I fully understand that this is because Ajax is Async call, so the question is how to restructure this code taking into account that I have two seperate files and I need to call getGeneral from outside and it should return some variable.

Share Improve this question edited Nov 21, 2013 at 13:16 renathy asked Nov 21, 2013 at 12:53 renathyrenathy 5,37520 gold badges92 silver badges155 bronze badges 5
  • possible duplicate of How to return the response from an AJAX call? – Rory McCrossan Commented Nov 21, 2013 at 12:53
  • Remember, the first A of AJAX means Asyncronous. Your getGeneral function has exited long before the AJAX call returns anything. – Rory McCrossan Commented Nov 21, 2013 at 12:54
  • Yes< I fully understand this, I am asking how to restructure it properly. – renathy Commented Nov 21, 2013 at 13:15
  • move applyBindings in the AJAX success function. Restructure you model so that you can do it this way. – Saturnix Commented Nov 21, 2013 at 13:20
  • I cannot move into ajax success as it is seperate file. – renathy Commented Nov 21, 2013 at 13:28
Add a ment  | 

1 Answer 1

Reset to default 5

Try using the returned promise interface:

function getGeneral(pid) {
    return $.ajax({
        url: "/api/general",
        contentType: "text/json",
        dataType: "json",
        type: "GET",
        data: {
            id: pid
        }
    });
}

getGeneral("@Model.Id").done(function (item) {
    var p = new GeneralModel();
    p = ko.mapping.fromJS(item);
    ko.applyBindings(p, document.getElementById("pv-portfolio-general-tab"));
}).fail(function () {
    //handle error here
});

I have getGeneral function that calls ajax GET. When ajax recieves data (json), it creates KO model from given json and returns created KO.

When Knockout model is created and values are assigned, knockout applybindings should be called. Here is my code:

Defines GeneralModel and some related functions (inside "GeneralModel.js"):

var GeneralModel = function() {

   //for now it is empty as data ar binded automatically from json
   // CountryName is one of the properties that is returned with json
} 

function getGeneral(pid) {
    $.ajax({
        url: "/api/general",
        contentType: "text/json",
        dataType: "json",
        type: "GET",
        data: { id: pid},
        success: function (item) {
            var p = new GeneralModel();
            p = ko.mapping.fromJS(item);
            return p;
        },
        error: function (data) {

        }
    });    
}

This is called from another file (GeneralTabl.html), it should call get function and applyBindings to update UI:

var PortfolioGeneral = getGeneral("@Model.Id");
ko.applyBindings(PortfolioGeneral, document.getElementById("pv-portfolio-general-tab"));

However, in this scenario I am getting error (CountryName is not defined). This is because applyBindings happens before ajax returns data, so I am doing applyBindings to empty model with undefined properties.

Mapping from Json to Model happens here and is assignes values: p = ko.mapping.fromJS(item);

I can also fill in GeneralModel with all fields, but it is not necessary (I guess):

  var GeneralModel = function() {    
      CountryName = ko.observable();
      ...
  } 

It will still give an error "CountryName is not defined".

What is the solution?

1) Can I somehow move getGeneral inside GeneralModel, so get data would be part of GeneralModel initialization?

or

2) Maybe I should somehow do "wait for ajax results" and only then applyBindings?

or

I believe there are other options, I am just not so familiar with KO and pure JS.

Note: I fully understand that this is because Ajax is Async call, so the question is how to restructure this code taking into account that I have two seperate files and I need to call getGeneral from outside and it should return some variable.

I have getGeneral function that calls ajax GET. When ajax recieves data (json), it creates KO model from given json and returns created KO.

When Knockout model is created and values are assigned, knockout applybindings should be called. Here is my code:

Defines GeneralModel and some related functions (inside "GeneralModel.js"):

var GeneralModel = function() {

   //for now it is empty as data ar binded automatically from json
   // CountryName is one of the properties that is returned with json
} 

function getGeneral(pid) {
    $.ajax({
        url: "/api/general",
        contentType: "text/json",
        dataType: "json",
        type: "GET",
        data: { id: pid},
        success: function (item) {
            var p = new GeneralModel();
            p = ko.mapping.fromJS(item);
            return p;
        },
        error: function (data) {

        }
    });    
}

This is called from another file (GeneralTabl.html), it should call get function and applyBindings to update UI:

var PortfolioGeneral = getGeneral("@Model.Id");
ko.applyBindings(PortfolioGeneral, document.getElementById("pv-portfolio-general-tab"));

However, in this scenario I am getting error (CountryName is not defined). This is because applyBindings happens before ajax returns data, so I am doing applyBindings to empty model with undefined properties.

Mapping from Json to Model happens here and is assignes values: p = ko.mapping.fromJS(item);

I can also fill in GeneralModel with all fields, but it is not necessary (I guess):

  var GeneralModel = function() {    
      CountryName = ko.observable();
      ...
  } 

It will still give an error "CountryName is not defined".

What is the solution?

1) Can I somehow move getGeneral inside GeneralModel, so get data would be part of GeneralModel initialization?

or

2) Maybe I should somehow do "wait for ajax results" and only then applyBindings?

or

I believe there are other options, I am just not so familiar with KO and pure JS.

Note: I fully understand that this is because Ajax is Async call, so the question is how to restructure this code taking into account that I have two seperate files and I need to call getGeneral from outside and it should return some variable.

Share Improve this question edited Nov 21, 2013 at 13:16 renathy asked Nov 21, 2013 at 12:53 renathyrenathy 5,37520 gold badges92 silver badges155 bronze badges 5
  • possible duplicate of How to return the response from an AJAX call? – Rory McCrossan Commented Nov 21, 2013 at 12:53
  • Remember, the first A of AJAX means Asyncronous. Your getGeneral function has exited long before the AJAX call returns anything. – Rory McCrossan Commented Nov 21, 2013 at 12:54
  • Yes< I fully understand this, I am asking how to restructure it properly. – renathy Commented Nov 21, 2013 at 13:15
  • move applyBindings in the AJAX success function. Restructure you model so that you can do it this way. – Saturnix Commented Nov 21, 2013 at 13:20
  • I cannot move into ajax success as it is seperate file. – renathy Commented Nov 21, 2013 at 13:28
Add a ment  | 

1 Answer 1

Reset to default 5

Try using the returned promise interface:

function getGeneral(pid) {
    return $.ajax({
        url: "/api/general",
        contentType: "text/json",
        dataType: "json",
        type: "GET",
        data: {
            id: pid
        }
    });
}

getGeneral("@Model.Id").done(function (item) {
    var p = new GeneralModel();
    p = ko.mapping.fromJS(item);
    ko.applyBindings(p, document.getElementById("pv-portfolio-general-tab"));
}).fail(function () {
    //handle error here
});

本文标签: javascriptwait for ajax result to bind knockout modelStack Overflow