2016-02-18 2 views
0

Я столкнулся с странным случаем, который, по-видимому, возникает только при первой загрузке компонента на странице компонента с высокой нагрузкой (загрузка 30+ компонентов).Угловое 2, устанавливающее новое значение, не вызывает событие изменения ввода

@Component{ 
    selector: <parent-component> 
    template: `<child-component [myObject]=myObject> 
} 
export class ParentComponent { 
    private myObject:DTOValue; 
    constructor(service:MyService){ 
     service.getDTOValue().subscribe((dtoValue:DTOValue) => { 
      this.myObject = dtoValue; 
     }); 
    } 
} 

@Component{ 
    selector: <child-component> 
    template: `<div></div> 
} 
export class ChildComponent { 
    @Input set myObject(value:DTOValue) => {//do something}; 
    constructor(){ 
    } 
} 

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

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

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

  1. Изменения входного быть Subject, так что я нажимаю значение входного сигнала, который должен гарантировать, что правильное событие срабатывает (это кажется излишним).

  2. Используйте динамический загрузчик, чтобы загрузить компонент, когда запрос будет возвращен с правильным значением (также кажется излишним).

UPDATE: Добавление plnker: http://plnkr.co/edit/1bUelmPFjwPDjUBDC4vb, вы можете увидеть здесь, что название кажется, никогда не получить применять его привязки данных.

Любые предложения будут оценены.

Спасибо!

ответ

1

Если вы можете определить, где проблема и соответствующий крючок жизненного цикла, где вы могли бы ее решить, вы можете позволить Angular узнать, используя ChangeDetectorRef.

constructor(private _ref: ChangeDetectorRef) 

method_where_changes_are_overlooked() { 
    do_something(); 
    // tell angular to force change detection 
    this._ref.markForCheck(); 
} 

У меня была аналогичная проблема, только с маршрутизатором - это нужно сделать перенаправление, когда/если сервер API переходит в автономный режим. Я решил это, отметив routerOnActivate() для проверки ...

Когда вы запускаете обнаружение изменений таким образом, «ветвь» дерева компонентов помечена для обнаружения изменений, от этого компонента до корня приложения. Вы можете посмотреть this talk by Victor Savkin по этому вопросу ...

+0

К сожалению, это решение не сработало. После некоторого копания кажется, что жизненный цикл ParentComponent никогда не срабатывает. Конструктор попадает, но если я добавлю ngOnInit, ngAfterViewInit, ни один из них не будет вызван. Я добавил кнопку к шаблону, который имеет метод щелчка. Если я нажму кнопку, жизненный цикл начнется, и все будет работать так, как я ожидал. Я думаю, вопрос в том, как я могу получить намерение, не используя кнопку для загрузки. – cjr

0

Извините, вопрос в конечном итоге был моим взаимодействием с jQuery. Когда я вызывал событие для компонента, который должен быть загружен, внутри кода jQuery, это не вызовет жизненный цикл. Исправление было после того, как код был загружен, чтобы затем вызвать обнаружение изменений.

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