2014-11-15 3 views
1

Моего Knockoutjs код идет следующим образом:Передача нокаута Наблюдается как параметр функции JavaScript?

function chainModel(){ 
     var self = this; 
     this.total_count = ko.observable(); 

     function get_total_count(number){ 
      $.ajax({ 
       type : "get", 
       url : "./XYZ/abc.php", 
       cache : false, 
       data : {number: number}, 
       success : function(result){ 
        self.total_count($.parseJSON(result)); 
       }, 
       error : function(jqXHR, textStatus, errorThrown){ 
        console.log("Error ! Unable to get step " + $number + " count." + "Error: " + errorThrown + ", Status: " + textStatus); 
       } 
      }); 
     } 
    } 

    ko.applyBindings(new chainModel()); 

Внутри функции get_total_count(), я назначаю Аякс результат self.total_count наблюдаемыми. Вместо этого я хотел бы передать наблюдаемый также как параметр функции get_total_count(), чтобы я мог повторно использовать одну и ту же функцию для более чем одного наблюдаемого.

+0

только что из любопытства: почему вы используете $ notation для параметра $ number? Это всего лишь номер? не объект jQuery – Daniel

+0

@ Daniel, Исправлено. Спасибо за указание. – Saurabh

+0

Что мешает вам пропустить наблюдаемый параметр? – Daniel

ответ

4

Вот другой подход, который использует семантику обещаний вызовов jQuery Ajax. Потратьте несколько минут, чтобы ознакомиться с jQuery Deferreds, если концепция для вас новая, она того стоит.

Быстрое примечание: по широко принятому соглашению имена конструкторов PascalCase, а все остальные имена - camelCase в JavaScript. Не используйте идентификаторы underscore_separated (никто не делает).

function ChainModel() { 
    var self = this; 

    self.totalCount = ko.observable(); 
    self.otherCount = ko.observable(); 

    function getCount(number) { 
     return $.get("./XYZ/abc.php", {number: number}) 
     .fail(function (jqXHR, textStatus, errorThrown) { 
      console.error(
       "Error ! Unable to get step " + number + " count." + 
       "Error: " + errorThrown + ", Status: " + textStatus 
      ); 
     }); 
    } 

    getCount(1).done(self.totalCount); 
    getCount(2).done(self.otherCount); 
} 

ko.applyBindings(new ChainModel()); 

С выколотки Наблюдаемые в действительности являются функциями и называть их устанавливает их значение, вы можете напрямую использовать их в качестве обратных вызовов успеха в Ajax звонки.

По возвращении jqXHR object от getCount() вы получаете доступ к функциям обещания, которые он предоставляет. Поэтому вместо прохождения в целевом наблюдаемом вgetCount() вы можете передать его на обратный вызов .done(), тем самым присвоив ему результат вызова Ajax. Эффективно это разделение проблем и делает ваш код более гибким.

Другие ноты:

  • Вы не должны заставить cache: false в вызов Ajax. Установите соответствующий заголовок Cache-Control на стороне сервера, и браузер не будет кэшировать вызов.
  • jQuery автоматически анализирует ответ для вас, вручную не нужно звонить $.parseJSON().
+0

Спасибо. Я все еще не понимаю, почему «$ .paseJSON()» не требуется, если моя функция PHP возвращает массив, индексированный по номеру столбца. Если я не использую '$ .parseJSON()', тогда он отображает данные как [{"1234"}]. – Saurabh

+0

Когда jQuery получает JSON-кодированный ответ, он автоматически декодирует его. Если после этого ваши данные ответа * еще * являются JSON, то очень вероятно, что он дважды закодирован на сервере - фактически ошибка, которую вы должны исправить на сервере. – Tomalak

0

Не так ли просто, как прохождение наблюдаемого в качестве аргумента?

function chainModel(){ 
    var self = this; 
    this.total_count = ko.observable(); 

    get_total_count(this.total_count, this.number); 

    function get_total_count(observable, number){ 
     $.ajax({ 
      type : "get", 
      url : "./XYZ/abc.php", 
      cache : false, 
      data : {number: number}, 
      success : function(result){ 
       observable($.parseJSON(result)); 
      }, 
      error : function(jqXHR, textStatus, errorThrown){ 
       console.log("Error ! Unable to get step " + number + " count." + "Error: " + errorThrown + ", Status: " + textStatus); 
      } 
     }); 
    } 
} 

ko.applyBindings(new chainModel()); 
0

Вы вызываете этот метод «get_total_count()» через любое связывание событий. Если это так, вы можете передать эту модель всей модели представления данных.

<input data-bind="event:{ click: function(data,event){ get_total_count(data,event,total_count()); } }" /> 
Смежные вопросы