Подождите, пока элемент будет определен в Angular2

Я пытаюсь встроить диаграмму Google на вкладку PrimeNG. Я использую ответвление пакета Angular 2 Google Chart. Первый раз перехожу на страницу с диаграммой, все работает как положено. Однако, когда я ухожу и возвращаюсь, я получаю следующую ошибку:

Ошибка в классе ./MyChartComponent MyChartComponent — встроенный шаблон: 1:5, вызванная: Контейнер #my_chart не определен.

Это та же самая ошибка, которую можно было бы получить, если бы они пытались нарисовать диаграмму в несуществующем div. Насколько я могу судить,

1) это работает в первый раз, потому что есть задержка при извлечении библиотеки диаграмм, что позволяет отображать элемент <div id="my_chart"...>. 2) при повторном открытии маршрута запускается последовательность событий, в результате которой библиотека диаграмм пытается установить содержимое div до того, как div будет включен в DOM.

Компоненты построения диаграмм работают нормально, если они не встроены во вкладки PrimeNG. Я подозреваю, что порядок, в котором происходят события, был нарушен этим. Я нашел ссылку, в которой говорится, что вкладки PrimeNG помещают контент в <ng-content>. Если это нарушает какие-то отношения родитель/потомок в жизненном цикле компонентов, то я также полагаю, что мне нужно каким-то образом подождать при установке @Input для компонента диаграммы до тех пор, пока не появится div "my_chart".

Я просмотрел документацию по различным крючкам жизненного цикла Angular, но не смог решить эту проблему. Любые советы будут оценены.


person Sevenless    schedule 14.11.2016    source источник


Ответы (1)


Попробуйте использовать атрибут разрешения при настройке маршрута:

{
    path: '',
    resolve: { chartData: ChartResolver },
    component: MyChartComponent 
}

Затем в вашем компоненте извлеките эти данные:

ngOnInit() {
    //The 'data' gets loaded into the snapshot by the route resolver 
    this.chartData = this.route.snapshot.data['chartData'];
  }

Затем вам нужно создать класс Resolver:

@Injectable()
export class ChartResolver implements Resolve<ChartData> {

  constructor(private http:Http) {}

  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<ChartData> {

    //Doesn't have to be a server call, as long as it returns the data
    return this.http.get("/url-to-chart-info)
      .map((res:Response) => res.json());
  }
}

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

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

person nfdavenport    schedule 15.11.2016