Вы хотите запросить функцию или сообщить об ошибке ?
Я не знаю, нужно ли это или это ошибка
Каково текущее поведение?
Первый вызов $onChanges
выполняется до $onInit
one.
С конфигурацией по умолчанию angular 1.6 (preassign = false) предпочтительно инициализировать состояния контроллера в функции $onInit
, поскольку привязки еще не доступны в конструкторе.
Какое ожидаемое поведение?
Думаю, логичнее было бы сначала назвать $onInit
.
Angular не должен ничего делать, пока контроллер не полностью инициализирован.
Какова мотивация / вариант использования для изменения поведения?
Если мы используем объекты, которые должны быть созданы в функции $onInit
в $onChanges
function; у нас будет ошибка при первом вызове, потому что контроллер еще не инициализирован.
Решением может быть инициализация этих объектов внутри конструктора, но мы инициализируем контроллер в двух разных местах ...
Какие версии Angular и какой браузер / ОС подвержены этой проблеме? Также проверьте последнюю стабильную версию и версию моментального снимка (https://code.angularjs.org/snapshot/).
угловая версия 1.6
Это предназначено (в основном, чтобы соответствовать поведению Angular 2+). Если вы его пропустили, вы можете проверить, является ли это первым (до $ onInit) вызовом $onChanges
, проверив возвращаемое значение метода isFirstChange()
любого из SimpleChange
объекты:
{
...
bindings: {foo: '<'},
controller: function SomeController() {
this.$onChanges = function(changes) {
if (changes.foo.isFirstChange()) {
// `$onInit()` has not been called yet...
}
};
}
}
Признаюсь, моя первая реакция была такой же. С точки зрения ментальной модели легче думать, что $onInit()
- это первое, что происходит в контроллере; затем $onChanges()
, $onChanges()
, $onChanges()
и, наконец, $onDestroy()
.
Но если подумать, привязки необходимо оценить и присвоить экземпляру контроллера перед вызовом $onInit
. Таким образом, обнаруживается изменение (ранее не заданных) значений, о котором, в свою очередь, необходимо сообщить через $onChanges
.
Закрытие, так как это работает, как ожидалось (или, по крайней мере, как задумано: wink :).
Большое спасибо за ответ, теперь понятнее :)
Я понимаю, что это сделано намеренно, как насчет того, чтобы зарегистрировать определение функции $ onChanges () внутри $ onInit ().
@bharatpatil , он должен работать в AngularJS (1.x.), но не в Angular (2+).
if (changes.foo.isFirstChange ()) {
//$onInit()
еще не был вызван ...
}
@gkalpak Я считаю, что это неверный аргумент. Метод binding.isFirstChange()
гарантирует только то, что связанная привязка была вызвана в первый раз. Подумайте о привязке, которая инициализируется после того, как вызов службы занимает слишком много времени. В этой ситуации метод controller.$onInit
следует вызывать перед методом controller.$onChanges
. Я ошибся?
Привязка всегда имеет значение в начале (может быть undefined
), которое всегда отличается от его предварительно инициализированного значения. Таким образом, $onChanges()
всегда будет вызываться с changes.foo
перед вызовом $onInit()
.
Нет логического смысла в том, что привязка может иметь значение до ее инициализации. Это словарное определение слова инициализировать (установить начальные значения). Вы не можете что-то изменить, если у него не было начального значения. Я думаю, что названия здесь неправильные и неестественные.
Я не могу вспомнить ситуацию, когда меня не заставляли писать что-то вроде этого кода:
$onChanges(changesObj: { [index: string]: angular.IChangesObject; }) {
if (!this.isInitialized) return;
...
}
Вызов «изменений» перед «инициализацией» не имеет никакого смысла.
Параллельно с Angular ... почему кто-то может ожидать, что init произойдет до изменений?
Самый полезный комментарий
Это предназначено (в основном, чтобы соответствовать поведению Angular 2+). Если вы его пропустили, вы можете проверить, является ли это первым (до $ onInit) вызовом
$onChanges
, проверив возвращаемое значение методаisFirstChange()
любого изSimpleChange
объекты:#
Признаюсь, моя первая реакция была такой же. С точки зрения ментальной модели легче думать, что
$onInit()
- это первое, что происходит в контроллере; затем$onChanges()
,$onChanges()
,$onChanges()
и, наконец,$onDestroy()
.Но если подумать, привязки необходимо оценить и присвоить экземпляру контроллера перед вызовом
$onInit
. Таким образом, обнаруживается изменение (ранее не заданных) значений, о котором, в свою очередь, необходимо сообщить через$onChanges
.Закрытие, так как это работает, как ожидалось (или, по крайней мере, как задумано: wink :).