2016-04-08 6 views
0

Я просмотрел и попытался несколько примеров по вызову функций синхронно, но, похоже, он не работает для меня. Я использую внешние шаблоны руля для генерации элемента «parent» html, загруженного данными, а затем после этого загружается, я хочу добавить html к нему из «дочерних» шаблонов, которые я создал (со своими собственными данными). Оба вызова функций вызывают одну и ту же функцию, но просто передаются в разных шаблонах/данных. Ниже приведен код, который у меня есть для этого - любая помощь приветствуется. Благодаря!Невозможно заставить эти две функции синхронно звонить

var loadSimpleCollection = function(templateFile, dataFile, containerSelector) { 

    var deferred = $.Deferred(); 

    $.get(templateFile, function(text) { 

    // Extract HTML from the template file 
    var raw_template = text; 

    // Compile that into an handlebars template 
    var template = Handlebars.compile(raw_template); 

    // Retrieve the container where the data will be displayed 
    var container = $(containerSelector); 

    // Fetch collection data from JSON file 
    $.getJSON(dataFile, function(data, status, xhr) { 
     $.each(data,function(index,element){ 
     var html = template(element); 
     container.append(html); 
     }); 
    }); 

    }); 

    return deferred.promise(); 

} 

loadSimpleCollection('template1.hbs', 'data1.json', '#parent-div').then(loadSimpleCollection('template1.hbs', 'data2.json', '#child-div')); 
+0

, вероятно, хотите, чтобы обернуть 'затем' выражение, в противном случае она вызывается немедленно. например '.then (function() {loadSimpleCollection (...)})' –

+0

Вам нужно решить возвращенное обещание 'deferred.resolve()' после 'container.append (html);' –

ответ

0

Есть несколько проблем с кодом:

  1. Вы никогда не разделяющими ваши отсроченный
  2. Там нет необходимости создавать свои собственные обещания - вы можете вернуть обещания у вас уже есть достаточно чем использовать the promise anti-pattern
  3. Вы звоните .then() неправильно, чтобы ваш код даже не дождался обещания, если вы правильно выполняете другое обещание.

Я хотел бы предложить следующее:

var loadSimpleCollection = function(templateFile, dataFile, containerSelector) { 

    return $.get(templateFile).then(function(text) { 

    // Compile that into an handlebars template 
    var template = Handlebars.compile(text); 

    // Retrieve the container where the data will be displayed 
    var container = $(containerSelector); 

    // Fetch collection data from JSON file 
    return $.getJSON(dataFile).then(function(data, status, xhr) { 
     $.each(data,function(index,element){ 
     var html = template(element); 
     container.append(html); 
     }); 
     return container; 
    }); 

    }); 

} 

loadSimpleCollection('template1.hbs', 'data1.json', '#parent-div').then(function() { 
    loadSimpleCollection('template1.hbs', 'data2.json', '#child-div') 
}); 

Изменения:

  1. Верните обещания у вас уже есть, а не создавать новые deferreds. Избегайте обещания анти-шаблона.
  2. Используйте обещания для ваших вызовов ajax.
  3. Цепные ваши две операции внутри асинхронных loadSimpleCollection() таким образом, они будут связаны друг с другом, и вызывающий абонент может знать, когда оба сделаны
  4. Передайте ссылку на функцию .then() так можно назвать позже, не выполняется немедленно.

Даже при всем этом, мне кажется странным, чтобы загрузить и компилировать же template1.hbs дважды. Вы, конечно, можете загрузить это один раз, скомпилировать его и затем использовать для нескольких других операций.

Вы могли бы сделать код работать быстрее, как это:

var p1 = $.get('template1.hbs'); 
var p2 = $.getJSON('data1.json'); 
var p3 = $.getJSON('data2.json'); 
$.when(p1, p2, p3).then(function(t, d1, d2) { 
    var template = Handlebars.compile(t[0]); 
    var container = $('#parent-div'); 
    $.each(d1[0], function(index, element) { 
     container.append(template(element)); 
    }); 
    container = $('#child-div'); 
    $.each(d2[0], function(index, element) { 
     container.append(template(element)); 
    }); 
}); 
+0

Perfect! Работал как шарм - спасибо jfriend00! – Heath

+0

@Heath - я добавил более быстрый вариант, который только загружает шаблон один раз и выполняет все вызовы ajax параллельно. – jfriend00

+0

@Heath. Поскольку похоже, что вы можете быть здесь новым, знаете ли вы, что когда вы ответите на свой вопрос, вы можете указать это сообществу, выбрав зеленую галочку рядом с лучшим ответом? И это также принесет вам некоторые точки репутации здесь при переполнении стека. – jfriend00

Смежные вопросы