Reputation: 25
I am attempting to reuse a kendoDropDownListBox and set the data by using a data-attribute in the parent to query the proper data source, combined with a switch case statement. The switch case portion of the code is not included as it works when the proper data is passed to it, I'm just unable to pull the proper data from the data-attribute (if I use buttons to pass the data it works fine)
I have tried a number of methods to pull the attribute including the following
element.dataset[keyname] element.getAttribute('keyname']
If I do a console.log('element') I can see the proper data, but either of the above two methods come up empty (either null or undefined).
The HTML:
<div [attr.data-message-id]="1"> Listbox Component
<app-listbox></app-listbox>
</div>
The Typescript:
import { Component, OnInit, ElementRef } from '@angular/core';
@Component({
selector: 'app-listbox',
styleUrls: ['./listbox.component.scss'],
template: `
<kendo-dropdownlist style="width:400px;"
[data]="data"
[filterable]="true"
[textField]="'text'"
[valueField]="'value'"
(filterChange)="handleFilter($event)"
>
<ng-template kendoDropDownListNoDataTemplate>
<div>
No data found.
<ng-container *ngIf="filter">Do you want to add new item - '{{ filter }}' ?</ng-container>
<br />
<button *ngIf="filter" class="k-button" (click)="addNew()">Add new item</button>
</div>
</ng-template>
</kendo-dropdownlist>
`
})
export class ListboxComponent {
public filter: string;
public source: Array<{ text: string, value: number }> = [
{ text: "Small", value: 1 },
{ text: "Medium", value: 2 },
{ text: "Large", value: 3 }
];
public data: Array<{ text: string, value: number }>;
messages = [
{
id: 1,
text: "Table1"
},
{
id: 2,
text: "Table2"
},
{
id: 3,
text: "Table3"
},
{
id: 4,
text: "Table4"
}
]
Table1 = [
{ id: 1, text: "small"},
{ id: 2, text: "med"},
{ id: 3, text: "large"},
{ id: 4, text: "XL"},
]
Table2 = [
{ id: 1, text: "ford"},
{ id: 2, text: "dodge"},
{ id: 3, text: "chevy"},
{ id: 4, text: "GM"},
]
Table3 = [
{ id: 1, text: "fiat"},
{ id: 2, text: "audi"},
{ id: 3, text: "Mercedes"},
{ id: 4, text: "BMW"},
]
Table4 = [
{ id: 1, text: "toyota"},
{ id: 2, text: "nissan"},
{ id: 3, text: "datsun"},
{ id: 4, text: "kia"},
]
constructor(private elRef: ElementRef) {
this.data = this.source.slice(0);
}
public addNew(): void {
this.source.push({
text: this.filter,
value: 0
});
this.handleFilter(this.filter);
}
public handleFilter(value) {
this.filter = value;
this.data = this.source.filter((s) => s.text.toLowerCase().indexOf(value.toLowerCase()) !== -1);
}
ngOnInit() {
console.log("OnInit");
console.log("el");
var el = this.elRef.nativeElement.parentElement.dataset;
console.log(el);
console.log("elatt");
var elatt = this.elRef.nativeElement.parentElement.attributes;
console.log(elatt);
console.log("elkey");
var elkey = this.elRef.nativeElement.parentElement.dataset['messageId'];
console.log(elkey);
console.log("att");
var att = this.elRef.nativeElement.parentElement.getAttribute(['data-message-id']);
console.log(att);
}
}
Using the above code, the el variable contains the following: enter image description here
The elatt variable contains the following: enter image description here
the elkey variable reports "undefined" and the att variable reports "null".
I'm sure I'm probably doing this the hard way, but being new to Angular, I'm not sure of a better way of doing this.
Ultimately what I'm looking for is a way to reuse the kendoDropdownBox as a component, and pass it the data it needs to display when it is used.
Upvotes: 0
Views: 4280
Reputation: 1400
ngOnInit() : Initialize the directive/component after Angular first displays the data-bound properties and sets the directive/component's input properties. Called once, after the first ngOnChanges().
ngAfterViewInit() : Respond after Angular initializes the component's views and child views / the view that a directive is in. Called once after the first ngAfterContentChecked().
You are not able to retrieve the data attribute from parent because, you are trying to access the parent from ngOnInit event. It should be in ngAfterViewInit Lifecyle event.
Refer the example below.
ParentComponent.html
<div [attr.data-message-id]="1">
<app-test-component></app-test-component>
</div>
ChildComponent.ts
import { Component, OnInit, ElementRef } from '@angular/core';
@Component({
selector: 'app-test-component',
templateUrl: './test-component.component.html',
styleUrls: ['./test-component.component.css']
})
export class TestComponentComponent implements OnInit {
constructor(private elRef: ElementRef) {
}
ngOnInit() {
}
ngAfterViewInit(){
console.log(this.elRef.nativeElement.parentElement);
console.log('message id : ', this.elRef.nativeElement.parentElement.dataset['messageId']);
}
}
Output Log
Upvotes: 2