2015-11-08 3 views
3

Я пытаюсь сделать индикатор выполнения, который обновляется по мере завершения большего количества задач. Однако компонент не может получить доступ к свойству, поскольку он не определен.Ember «this» undefined in component

Я ввел службу, и я пытаюсь создать вычисленное свойство из свойства службы. Однако это всегда не определено, если только в отладке.

import Ember from 'ember'; 

export default Ember.Component.extend({ 
    progress: 0, 
    game: Ember.inject.service(), 
    events: this.get("game.challenges") 
}); 

Как это быть определено в приведенном выше коде? Как это не связано с какой-либо областью?

Я бросил в отладчике, как это:

init() { 
    debugger 
}, 

Если я выйти из this.get("game") возвращает ожидаемое значение.

Я также попытался включить службу внутри init, но все еще не определено. Я попытался вывести это, и это тоже не определено.

Есть ли способ заставить службу решить, прежде чем двигаться дальше? Я пробовал использовать различные крючки компонентов, но они, похоже, ничего не изменили.

+0

Возможный дубликат [столпотворение экспортирует "это" как неопределенные в Ember вычислен собственности] (HTTP: // StackOverflow. com/questions/31283175/babel-is-exporting-this-as-undefined-in-ember-computed-property) –

ответ

1

Вы должны сказать Ember, что это вычисленное свойство. Рассчитанные свойства очень хорошо задокументированы в документации -

http://guides.emberjs.com/v2.0.0/object-model/computed-properties/

Если вы просто хотите, чтобы это было то же самое значение, от службы, вы можете псевдоним его следующим образом:

game: Ember.computed.alias('game.challenges')

+0

Проблема в этом нет, вычисленное свойство, это то, что это не определено вообще. Если я попытаюсь создать вычисляемое свойство на основе атрибута службы, он терпит неудачу, потому что он получает ошибку типа при этом. – user3162553

+0

Возможно, мне просто нужно сделать это псевдонимом. Сначала я хотел преобразовать число в процентах, но это просто невозможно. – user3162553

+0

'this' не соответствует контексту, если вы просто выбросите его там, где у вас его есть, поэтому, конечно, он не определен. Оберните его в свою собственную функцию или в функцию Ember.computed, и она будет правильно ссылаться на ваш компонент. –

3

развивавших на ответ Тома:

В JS this является видом специальной переменной. Его значение зависит от того, находится ли оно внутри функции или нет.

  • Внешняя функция, это глобальный контекст (в браузере, обычно это объект window).
  • Внутри функции это объект, на который вызывается функция. Например, если вы напишете obj.f(), то this будет obj в f(). Если вы вызываете функцию напрямую, this остается тем, чем он является в настоящее время.

В вашем коде двигатель JS в настоящее время выполняется вне функции (он готовится к вызову extend, передавая ему объект).

export default Ember.Component.extend({ 
    game: Ember.inject.service(), 
    events: this.get("game.challenges") 
}); 

Поэтому this в вашем коде относится к window объекта. Вы исправить с помощью computed property, то есть функция, которая вызывается для объекта, когда свойство получено:

export default Ember.Component.extend({ 
    game: Ember.inject.service(), 
    events: Ember.computed('game.challenges', function() { 
    return this.get("game.challenges"); 
    }) 
}); 

Вы можете делать все, что вам нужно вычисление в функции. Просто помните, что все зависит от результата, должно быть указано внутри property(), поэтому Ember знает, когда его пересчитать.

Наконец, для некоторых распространенных случаев, уголек предоставляет некоторые shortcuts, такие как Ember.computed.alias, Ember.computed.equal ...

+0

Способ, которым я раньше пытался понять это, заключается в том, что он основан на том, как функция была вызвана. Проблема, о которой я думаю, была в том, что она была в каркасе, я не был уверен, что в игре есть другие вещи. Я также подумал, что это будет найдено для компонента, потому что я не уверен, как Эмбер работает за сценой. Ваше объяснение имеет большое значение, хотя и я лучше понимаю, что происходит. – user3162553