I want Wijmo FlexGrid column width should cover full width.
As I'm dynamically assigning the columns so can't use [width]="'*'"
Assign a template reference variable to the grid. E.g. flex1
<wj-flex-grid #flex1
[itemsSource]="data">
<wj-flex-grid>
Then in the ngAfterViewInit callback set up your columns and assign the column in question the width '*', e.g.
import { Component, ViewChild, AfterViewInit } from '#angular/core';
import { Collection } from 'wijmo/wijmo';
import { FlexGrid } from 'wijmo/wijmo.grid';
#Component({ ... })
export class MyComponent implements AfterViewInit {
#ViewChild('flex1') protected grid: FlexGrid;
protected data: any;
constructor() {
this.data = new Collection([
{ id: 1, country: 'United States' },
{ id: 2, country: 'Germany' },
]);
}
public ngAfterViewInit() {
// Missing part: Set up columns programmatically
// OP has done this already.
// Set the column width of the column with binding to the `country` property
this.grid.columns.getColumn('country').width = '*';
}
}
Related
I've got a Question regarding TypeORM-Relations and how to use them 'nest-like'.
Suppose I have two Entities defined ChildEntity and TestEntity, which are related.
TestEntity:
import { ChildEntity } from 'src/modules/child-entity/entities/child-entity.entity';
import { Column, Entity, ManyToOne, PrimaryGeneratedColumn } from 'typeorm';
#Entity()
export class TestEntity {
#PrimaryGeneratedColumn()
id: number;
#Column('varchar')
name: string;
#ManyToOne(() => ChildEntity, (childEntity) => childEntity.testEntities)
childEntity: ChildEntity;
constructor(name: string, childEntity: ChildEntity) {
this.name = name;
this.childEntity = childEntity;
}
}
My first question occurs when I want to create the entity. I have to first translate the passed childEntityId into a ChildEntity, which I can pass to the constructor:
CreateTestEntityDto
import { ApiProperty } from '#nestjs/swagger';
import { IsNotEmpty, IsNumber } from 'class-validator';
export class CreateTestEntityDto {
#ApiProperty()
#IsNotEmpty()
name: string;
#ApiProperty()
#IsNumber()
childEntityId: number;
constructor(name: string, childEntityId: number) {
this.name = name;
this.childEntityId = childEntityId;
}
}
async create(createTestEntityDto: CreateTestEntityDto) {
const { name, childEntityId } = createTestEntityDto;
const childEntity = await this.childEntityService.findOne(childEntityId);
const testEntity = new TestEntity(name, childEntity);
return this.testEntityRepo.save(testEntity);
}
Is there a way to just pass the childEntityId to the save()-Method without explicitly looking for the ChildEntity beforehand?
The Second problem occurs when updating.
UpdateTestEntityDto
import { PartialType } from '#nestjs/swagger';
import { CreateTestEntityDto } from './create-test-entity.dto';
export class UpdateTestEntityDto extends PartialType(CreateTestEntityDto) {}
As updating only a partial Entity is possible I have to check if the Id is even passed along the request and if it is I have to retrieve the correct Entity for the update. Is there a more streamlined way to do this?
async update(id: number, updateTestEntityDto: UpdateTestEntityDto) {
const { name, childEntityId } = updateTestEntityDto;
const props = { name };
if (childEntityId) {
props['childEntity'] = await this.childEntityService.findOne(
childEntityId,
);
}
return this.testEntityRepo.update(id, props);
}
You should add a childEntityId to the test entity:
#Entity()
export class TestEntity {
#PrimaryGeneratedColumn()
id: number;
#Column('varchar')
name: string;
#Column('int')
childEntityId: number;
#ManyToOne(() => ChildEntity, (childEntity) => childEntity.testEntities)
childEntity: ChildEntity;
...
}
and then you can use it to set the id directly. Something like:
async create(dto: Dto) {
const { name, childEntityId } = dto;
const entity = new TestEntity();
entity.name = name;
entity.childEntityId = childEntityId;
return this.testEntityRepo.save(entity);
}
Check this out.
1.) Saving relational entity
There's no need to do all these roundtrips cluttering to save the entity. While, the solution given by #UrosAndelic works but still there's no need to write 3 extra lines of code.
If you hover over a relational param inside the create() method of the repository from an IDE, you'll notice that it accepts two types. First, An Instance of an entity OR Second, a DeepPartial object of an entity.
For instance:
const entity = this.testEntityRepo.create({
name: 'Example 1',
childEntity: {
id: childEntityId // notice: it's a DeepPartial object of ChildEntity
}
})
await this.testEntityRepo.save(entity)
2.) Updating entity
There's no need for child entity's id if you are updating test entity. You can simply update the props of test entity.
const testEntityId = 1;
await this.testEntityRepo.update(testEntityId, {
name: 'Example 2'
})
This will update the name of TestEntity = 1;
So I'm trying to perform some action on the parent component of the child component when a click event is fired in the child component. Currently I have a dynamic loader which is able to load different child components. The problem I have is that the #Output() is being emitted but the parent component doesn't seem to have any knowledge when this event is fired. Is there something I am missing?
child2.component.ts
import {Component, Injector, Output, EventEmitter} from '#angular/core';
#Component({
selector: 'hello-world',
template: `
<div>Hello World {{showNum}}</div>
<li (click)="childButtonClicked(false)"> </li>
`,
})
export class HelloWorldComponent {
showNum = 0;
#Output() childEvent = new EventEmitter<boolean>();
constructor(private injector: Injector) {
this.showNum = this.injector.get('showNum');
console.log("HelloWorldComponent");
}
childButtonClicked(agreed: boolean) {
this.childEvent.emit(agreed);
console.log("clicked");
}
}
child1.component.ts
import {Component, Injector, Output, EventEmitter} from '#angular/core';
#Component({
selector: 'world-hello',
template: `
<div>World Hello {{showNum}}</div>
<li (click)="childButtonClicked(false)"> </li>
`,
})
export class WorldHelloComponent {
showNum = 0;
#Output() childEvent = new EventEmitter<boolean>();
constructor(private injector: Injector) {
this.showNum = this.injector.get('showNum');
console.log("WorldHelloComponent");
}
childButtonClicked(agreed: boolean) {
this.childEvent.emit(agreed);
console.log("clicked");
}
}
dynamic.componentloader.ts
import {Component, Input, ViewContainerRef,ComponentRef, ViewChild, ReflectiveInjector, ComponentFactoryResolver} from '#angular/core';
#Component({
selector: 'dynamic-component',// Reference to the components must be here in order to dynamically create them
template: `
<div #dynamicComponentContainer></div>
`,
})
export class DynamicComponent {
currentComponent:any = null;
#ViewChild('dynamicComponentContainer', { read: ViewContainerRef }) dynamicComponentContainer: ViewContainerRef;
// component: Class for the component you want to create
// inputs: An object with key/value pairs mapped to input name/input value
#Input() set componentData(data: {component: any, inputs: any }) {
if (!data) {
return;
}
// Inputs need to be in the following format to be resolved properly
let inputProviders = Object.keys(data.inputs).map((inputName) => {return {provide: inputName, useValue: data.inputs[inputName]};});
let resolvedInputs = ReflectiveInjector.resolve(inputProviders);
// We create an injector out of the data we want to pass down and this components injector
let injector = ReflectiveInjector.fromResolvedProviders(resolvedInputs, this.dynamicComponentContainer.parentInjector);
// We create a factory out of the component we want to create
let factory = this.resolver.resolveComponentFactory(data.component);
// We create the component using the factory and the injector
let component = factory.create(injector);
// We insert the component into the dom container
this.dynamicComponentContainer.insert(component.hostView);
// We can destroy the old component is we like by calling destroy
if (this.currentComponent) {
this.currentComponent.destroy();
}
this.currentComponent = component;
}
constructor(private resolver: ComponentFactoryResolver) {
}
}
main.component.ts
import { Component, OnInit } from '#angular/core';
import { HelloWorldComponent } from '../../views/main/sidebar-views/comps/hello-world.component';
import { WorldHelloComponent } from '../../views/main/sidebar-views/comps/world-hello.component';
#Component({
selector: 'main-component',
template: require('./main.component.html')
})
export class MainComponent {
private pressed: boolean = false;
componentData:any = null;
constructor() { }
createHelloWorldComponent(){
this.componentData = {
component: HelloWorldComponent,
inputs: {
showNum: 9
}
};
}
createWorldHelloComponent(){
this.componentData = {
component: WorldHelloComponent,
inputs: {
showNum: 2
}
};
}
test(){
console.log("some click event");
}
};
main.component.html
<div>
<h2>Lets dynamically create some components!</h2>
<button (click)="createHelloWorldComponent()">Create Hello World</button>
<button (click)="createWorldHelloComponent()">Create World Hello</button>
<dynamic-component [componentData]="componentData" (childEvent)="test()"></dynamic-component>
</div>
Since you are passing a parameter to the EventEmitter, you need to change your event binding on your component selector in your template to this:
<dynamic-component [componentData]="componentData" (childEvent)="test($event)"></dynamic-component>
Also, don't forget to change function signature in your component to accept the parameter:
test(agreed: boolean){
console.log("some click event");
}
More info on official docs.
i have a service that returns an API response of type json, in this json object i have a list of number values.i can output those values on my webpage, but i would like to store the values in an array first to do some calculations on. i have tried many ways without success. please guide me
API response screenshot in postman
http call service
getTriggerCount():Observable<Trigger>{
return this.http.get(this.triggersUrl).pipe(
flatMap(count => transformAndValidate(Trigger, count)))
component
#Component({
selector: 'app-triggers',
templateUrl: './triggers.component.html',
styleUrls: ['./triggers.component.css']
})
export class TriggersComponent implements OnInit {
#Input() trigger: Trigger;
constructor(private triggerService: DbApiService) { }
ngOnInit() {
this.getTriggerCount();
}
getTriggerCount(){
this.triggerService.getTriggerCount() .subscribe(trigger => this.trigger = trigger);
}
}
Trigger Class
import { IsNumber, IsNotEmpty, IsString } from 'class-validator';
export class Trigger {
#IsNotEmpty()
#IsNumber()
result: number[];
constructor() { }
}
The issue is with your service, it should be like the following
getTriggerCount():Observable<any>{
return this.http.get(this.triggersUrl).map(res => res.json());
}
Using the new HttpClient it should like like this:
getTriggerCount():Observable<any>{
return this.http.get<any>(this.triggersUrl);
}
To make use of this in the component. You also do not need the #Input() for trigger. Your Trigger class is also over complicated for what you are doing. See below
public trigger: any;
getTriggerCount(){
this.triggerService.getTriggerCount()
.subscribe(trigger => this.trigger = trigger);
}
This will then have the response on the trigger object. If you want to make use of the object, to say, add all the numbers together, you would do the following:
addArray() {
let sum = this.trigger.reduce((a, b) => +a + +b, 0);
}
The +a and +b is to convert the item to a number. This won't work if the item can't convert to a number.
I've been following example straight from demo app. Nevertheless, I get an error when using addAll() method to add table data to the model:
Error in ./MdlTableComponent class MdlTableComponent - inline template:7:18 caused by: Cannot read property 'columns' of undefined
Code is below, any insights would be greatly appreciated! (I simplified code and hard-coded table data).
import { Component, OnInit } from '#angular/core';
import {
MdlDialogService, MdlDefaultTableModel, IMdlTableModelItem
} from 'angular2-mdl';
export interface ITableItem extends IMdlTableModelItem {
fname: string;
fsize: number;
ftype: string;
}
#Component({
...
})
export class MyComponent implements OnInit {
public fileListModel: MdlDefaultTableModel = new MdlDefaultTableModel(
[
{ key: 'fname', name: 'File Name' },
{ key: 'fsize', name: 'File Size', numeric: true },
{ key: 'ftype', name: 'File Type' }
]);
public fileListData: [ITableItem] = [
{
fname: 'aaa.png',
fsize: 500,
ftype: 'image/png',
selected: true
}];
ngOnInit(): void {
this.fileListModel.addAll(this.fileListData); // Error is thrown here
Check your corresponding template. It should be using fileListModel
<mdl-table-selectable mdl-shadow="2"
[table-model]="fileListModel"
[table-model-selected]="selected"
(table-model-selectionChanged)="selectionChange($event)">
</mdl-table-selectable>
i am trying to modify the value of the numeric text box but while updating it creates a never ending loop. the model binding should update only once
Component below
import { Component } from '#angular/core';
#Component({
selector: 'my-app',
template: `<kendo-numerictextbox
[spinners]="showButtons"
[restrictDecimals]="true"
[round]="false"
[decimals]="decimals"
[format]="c2"
[ngModel]="value"
(ngModelChange)="onValueChange($event)"></kendo-numerictextbox> `
})
export class AppComponent {
public showButtons: boolean = false;
public format: string;
public decimals: number = 2;
public value: number = 0;
onValueChange(value: string) {
this.value = value + ' USD';
alert(value);
}
}
attached plnkr : http://plnkr.co/edit/kjl7e1wrFJGmpKa008cT
Note that the component works with digits only and the value that you are passing is invalid.