Невозможно прочитать свойство "показать" неопределенного

У меня есть два компонента: клиентский и клиентский компоненты. Компоненты клиентов содержат список клиентов, и когда я нажимаю на клиента, компонент клиента должен открывать модальное окно.

customers.component.ts

import { Component, OnInit, } from '@angular/core';

import { CustomerComponent } from '../customer/customer.component';

export class Customer {
  id: number;
  name: String;
}

const CUSTOMERS: Customer[] = [
  {
    id: 1,
    name: 'Customer one'
  },
  {
    id: 2,
    name: 'Customer two'
  }
];

@Component({
  selector: 'app-customers',
  templateUrl: './customers.component.html',
  styleUrls: ['./customers.component.css'],
  providers: [
    CustomerComponent
  ]
})
export class CustomersComponent implements OnInit {
  title: String;
  customers: Customer[] = CUSTOMERS;
  customerComponent: CustomerComponent;
  // or
  @ContentChild(CustomerComponent)
  public customerComponent: CustomerComponent;

  constructor() {
    this.title = 'Customers';

    this.customerComponent = new CustomerComponent();
    // tried removing
  }

  ngOnInit() {
  }

  showCustomer(customer: Customer) {
    this.customerComponent.openModal(customer);
  }
}

customers.component.html

<app-customer></app-customer>
<div id="page-wrapper">
  <div class="container-fluid">
    <div class="row">
      <div class="col-lg-12">
        <h1 class="page-header">{{title}}</h1>
      </div>
    </div>
    <div class="row">
      <div class="col-lg-12">
        <div class="panel panel-default">
          <div class="panel-heading">
            De klanten pagina
          </div>
          <div class="panel-body">
            <div class="table-responsive">
              <table class="table table-striped table-bordered table-hover">
                <thead>
                <tr>
                  <th>#</th>
                  <th>Name</th>
                </tr>
                </thead>
                <tbody *ngFor="let customer of customers;">
                <tr (click)="showCustomer(customer)" [style.cursor]="'pointer'">
                  <td>{{customer.id}}</td>
                  <td>{{customer.name}}</td>
                </tr>
                </tbody>
              </table>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

Таким образом, после щелчка по tr компонент CustomersComponent должен показать модальное окно.

customer.component.ts

import { Component, OnInit, ViewChild } from '@angular/core';
import { Customer } from '../customers/customers.component';
import { ModalDirective } from 'ngx-bootstrap';

@Component({
  selector: 'app-customer',
  templateUrl: './customer.component.html',
  styleUrls: ['./customer.component.css'],
})
export class CustomerComponent implements OnInit {
  @ViewChild('lgModal') public lgModal: ModalDirective;
  // or
  @ViewChild(ModalDirective) public lgModal: ModalDirective;

  constructor() {
  }

  ngOnInit() {
  }

  openModal(customer: Customer): void {
    console.log(customer);
    console.log(this.lgModal);

    this.lgModal.show();
  }
}

И customer.component.html

<div bsModal #lgModal="bs-modal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel" aria-hidden="true">
  <div class="modal-dialog modal-lg">
    <div class="modal-content">
      <div class="modal-header">
        <h4 class="modal-title pull-left">Large modal</h4>
        <button type="button" class="close pull-right" (click)="lgModal.hide()" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body">
        ...
      </div>
    </div>
  </div>
</div>

console.log(this.lgModal); возвращает undefined, а this.lgModal.show(); выдает ERROR TypeError: Cannot read property 'show' of undefined ошибку ..

изменить:

Пытался добавить <app-customer></app-customer> в customers.component.html


person yooouuri    schedule 03.07.2017    source источник
comment
Возможный дубликат ng2-bootstrap показать / скрыть модальное окно как дочерний компонент   -  person Aravind    schedule 03.07.2017


Ответы (3)


Я нашел решение вашей проблемы благодаря этой проблеме: https://www.bountysource.com/issues/35264857-how-to-call-modal-from-parent-component

Внесенные изменения должны иметь ребенка как exportAs: 'child' (например)

@Component({
  ....
  exportAs: 'child'
})

Тогда в родительском шаблоне есть:

<app-customer #c="child"></app-customer>

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

(click)="c.openModal(customer)" 

а в дочернем вы объявляете свой @ViewChild:

@ViewChild('lgModal') public lgModal: ModalDirective;

Это должно сработать!

Вот ДЕМО, с которым можно поиграть :)

person AJT82    schedule 03.07.2017
comment
В качестве комментария могу сказать, что не знаю, почему это не сработает с внесением изменений, предложенных ThinkingMedia. На мой взгляд, это должно работать ... - person AJT82; 03.07.2017

@ViewChild и другие привязки запросов к содержимому используют функцию конструктора компонента для поиска совпадений. Когда вы передаете строку, предполагается, что вы имеете в виду токен внедрения зависимости.

Вам нужно изменить код на этот:

 @ViewChild(ModalDirective) public lgModal: ModalDirective;

Примечание. Вы не можете запрашивать абстрактные классы или интерфейсы. Это должен быть тип компонента или директивы.

Изменить:

Так нельзя создавать компоненты:

this.customerComponent = new CustomerComponent();

Это не сработает, поскольку для создания компонентов необходимо использовать Angular. Попробуйте добавить компонент клиента в шаблон клиентов, а затем используйте @ContentChild для доступа к этому компоненту.

@ContentChild(CustomerComponent)
public customerComponent: CustomerComponent;

Ссылка для @ContentChild будет установлена ​​AfterContentInit.

person Reactgular    schedule 03.07.2017
comment
К сожалению, это не имеет значения. По-прежнему undefined ошибка - person yooouuri; 03.07.2017
comment
@Yooouuri Это правильное использование ViewChild. Я подозреваю, что у вас проблема где-то еще. Какую библиотеку начальной загрузки вы используете? - person Reactgular; 03.07.2017
comment
@Yooouuri Я только что увидел твою ошибку. См. Обновление выше. - person Reactgular; 03.07.2017
comment
@Yooouuri, это сработает. Вы движетесь в правильном направлении. Вам необходимо обновить свой вопрос, если вы устранили вышеуказанные проблемы. - person Reactgular; 03.07.2017
comment
@Yooouuri <app-customer></app-customer> необходимо добавить в шаблон клиентов. - person Reactgular; 03.07.2017

У меня была аналогичная проблема. Показанная ошибка была undefined, и невозможно прочитать свойство 'hide' of undefined ... Я решил это, добавив в (дочерний) конструктор мой модальный, как показано ниже, который был реализован в родительском компоненте.

конструктор (общедоступный openModalDetails: BsModalRef) {}

person Ramona Stoica    schedule 02.08.2019