Angular — элемент конструктора не определен в функции

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

Вот мой файл компонента:

export class ProductsComponent implements OnInit {
  dataSource: any;
  priority: any[];
  e: any;

  constructor(public dataService: DataService) {
      // data source stuff...
  }

  ngOnInit() {
    console.log(this.dataService) //successfully shows DataService object
  }

  addToCart(e) {
    console.log(e.row.data["Task_Subject"]);
    console.log(this.dataService) // undefined?!?
    this.dataService.addItem(e.row.data["Task_Subject"])
  }
}

И HTML-шаблон компонента:

<h2 class="content-block">Products</h2>

<dx-data-grid class="dx-card wide-card" [dataSource]="dataSource" [showBorders]="false" [focusedRowEnabled]="true"
  [focusedRowIndex]="0" [columnAutoWidth]="true" [columnHidingEnabled]="true">

  <dxo-paging [pageSize]="10"></dxo-paging>
  <dxo-pager [showPageSizeSelector]="false" [showInfo]="true"></dxo-pager>
  <dxo-filter-row [visible]="true"></dxo-filter-row>

  <dxi-column dataField="Task_ID" [width]="90" [hidingPriority]="2">
  </dxi-column>
  <dxi-column dataField="Task_Subject" [width]="190" caption="Subject" [hidingPriority]="8">
  </dxi-column>
  <dxi-column dataField="Task_Status" caption="Status" [hidingPriority]="6">
  </dxi-column>
  <dxi-column dataField="Task_Priority" caption="Priority" [hidingPriority]="5">
    <dxo-lookup [dataSource]="priority" valueExpr="value" displayExpr="name">
    </dxo-lookup>
  </dxi-column>
  <dxi-column dataField="ResponsibleEmployee.Employee_Full_Name" caption="Assigned To" [allowSorting]="false"
    [hidingPriority]="7">
  </dxi-column>
  <dxi-column caption="Actions" type="buttons" [hidingPriority]="0">
    <dxi-button icon="plus" [onClick]="addToCart">Action</dxi-button>
  </dxi-column>
</dx-data-grid>

Когда я нажимаю кнопку «dxi-button», запускается функция addToCart(). В функции ngOnInit служба данных отображается, но в функции addToCart служба данных ведения журнала консоли дает мне неопределенное значение.

Что я делаю не так? Кстати, я использую DevExtreme.


person Mert Can Bilgiç    schedule 20.10.2020    source источник
comment
DevExtreme делает что-то странное с вложенными компонентами. Обычно вы должны использовать () для привязки событий. Я предполагаю, что они неправильно устанавливают «это», console.log «это» и смотрят, что это такое. документы   -  person Jason Goemaat    schedule 20.10.2020
comment
эта библиотека, которую вы используете, похоже, передает вам функцию вместо традиционной привязки событий. Для меня это огромный красный флаг, который подразумевает, что эта библиотека плохо интегрирована с angular, и поэтому вы можете избегать ее использования в контексте angular.   -  person bryan60    schedule 20.10.2020
comment
@JasonGoemaat, спасибо, я console.log 'это', и он дал мне объект, подобный этому {cssClass: undefined,icon: plus,name: undefined,onClick: ƒ addToCart(),text:undefined}   -  person Mert Can Bilgiç    schedule 20.10.2020


Ответы (3)


Я думаю, что то, как вы вызываете свою функцию, не в угловом контексте.

Попробуйте сделать console.log(this), и если объект не относится к типу ProductsComponent, то вы больше не находитесь в угловом контексте.

Если это так, вы можете изменить способ вызова функции onClick внутри вашего html-шаблона.

может что-то вроде

(onClick)="addToCart(item)"
person Alann    schedule 20.10.2020
comment
Этот способ не работает, потому что мой путь — это подход DevExtreme к документации. Когда я попробовал настоящие угловые контексты, это дало мне, что button.onclick.call не является ошибкой функции. Это единственный способ заставить кнопку работать, но... я не знаю, почему она не работает. - person Mert Can Bilgiç; 20.10.2020
comment
@MertCanBilgiç, можете ли вы предоставить нам stackblitz с вариантом использования? - person Alann; 20.10.2020
comment
из того, что я вижу в документации, вы можете связать функцию (onClick) внутри компонента devExtreme - person Alann; 20.10.2020

Я исправил небольшой трюк, опубликовав ответ для других людей. Devexpress изменить масштаб этого. Для решения этого я просто добавил

this.addToCart = this.addToCart.bind(this);

в конструктор, и теперь я могу правильно использовать this.dataService! Спасибо за вашу помощь, ребята.

person Mert Can Bilgiç    schedule 20.10.2020

Глядя на документы по функциям обратного вызова для компонентов devextreme, привязка сделано очень неугловым способом.

В angular и для компонентов верхнего уровня вы можете использовать привязку (). Поскольку вложенные компоненты используют синтаксис привязки [], вам нужно передать ему функцию, которая привязана к объекту, который вы хотите сделать «этим» внутри функции. Он рекомендует сделать это в вашем конструкторе:

Функции обратного вызова выполняются вне контекста компонента. Если контекст важен, явно привяжите к нему функцию обратного вызова в конструкторе.

  constructor(public dataService: DataService) {
      // data source stuff...
      this.addToCart.bind(this);
  }
person Jason Goemaat    schedule 20.10.2020