2015-09-22 2 views
2

В Ember вы можете ссылаться на свойство в шаблоне, и шаблон будет ожидать, что это свойство будет заполнено перед рендерингом.Ждите свойства в EmberJS на стороне «сервера»

Это прекрасно работает для получения списка записей, которые заполняются внешним REST конечной точки:

App.ItemsListRoute = Ember.Route.extend({ 
    model: function() { 
     return { 
      client: App.Client.create() 
     } 
    } 
}); 

Где конструктор клиента выглядит следующим образом:

App.Client = Ember.Object.extend({ 
    init: function() { 
     var _this = this; // For referencing in AJAX callback 
     $.ajax({ 
      url: MY_API_URL, 
      type: 'GET' 
     }).done(function(res) { 
      _this.set('itemsList', parsedDataFromRes); 
     }); 
    }, 
}); 

Для моего шаблона, опирающейся на itemsList, это отлично работает:

... 
{{#each item in model.client.itemsList}} 
     <tr> 
... 

Однако, у меня есть другой маршрут для статистики, в которой я хотел бы сделать некоторые расчеты по результатам запроса и возвращаю этих значения шаблона:

App.StatsPageRoute = Ember.Route.extend({ 
    model: function() { 
     var itemCount = getClient().get('itemsList').length; 
     return { 
      numItems: itemCount 
     } 
}) 

Я понимаю, что это надуманный пример - я мог бы запросить length на шаблоне, и это сработает хорошо - но вам придется смеяться над мной.

Проблема с приведенным выше примером заключается в том, что get('itemsList'), скорее всего, вернет неопределенное значение, основанное на расчете данных для визуализации шаблона, и вызванный ответ AJAX и определитель свойств.

Как я могу «подождать», чтобы свойство стало доступным в моем JS (а не в шаблоне), чтобы его можно было использовать для предоставления модели для шаблона?

Преобразует свойство 'itemsList' в функцию, возвращающую обещание наиболее «Ужасно-как» способ делать что-то? Будет ли это сильно осложнять мою логику шаблонов?

ответ

2

Вы можете использовать обещание и выполнить дополнительную операцию в вызове функции then. Например, вы можете сделать

App.StatsPageRoute = Ember.Route.extend({ 
    model: function() { 
     var itemCount = getClient().then(function(promiseResult){ 
      var itemCount = promiseResult.get('itemsList').length; 
      return { 
      numItems: itemCount 
      } 
     }) 
}) 

Чтобы использовать это, однако, вы должны убедиться, что getClient возвращает обещание. Я предложил вам использовать ic-ajax (включен в Ember). Это абстракция над jQuery ajax, которая возвращает обещания вместо ожидающих успехов и обратных вызовов ошибок.

Кроме того, я настоятельно рекомендую вам взглянуть на ember-data и попытаться построить бэкэнд, соответствующий спецификации. Таким образом, у вас есть хорошая абстракция для ваших данных, и это значительно увеличивает скорость разработки, так как вам не нужно беспокоиться о взаимодействии с бэкэнд.

Редактировать: Возвращение обещания вместо данных не повлияет на вашу логику шаблона. Ember решит обещание, и цикл запуска Ember автоматически обновит шаблон при изменении значения. То, что вы, возможно, захотите, хотя, возможно, имеет значение по умолчанию или какой-либо счетчик. Однако это, вероятно, то, что вы бы сделали, независимо от того, вернула ли ваша модель обещание или нет.

+0

Если я изменю функцию getClient() ', чтобы вернуть обещание, как это изменит логику на моей странице шаблона? –

+0

@CraigOtis, я обновил свое сообщение, чтобы ответить на ваш вопрос. Не стесняйтесь спрашивать о дополнительных разъяснениях. – QuantumLicht

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