I want to get parent component of child component in current view from .ts file in Angular. After I searched a lot , I could not find. I think easiest things can not be found in ANgular so I am really suprised why it is so popular. Anyway , let me tell what I do.
Think that in parent component 1 and 2 html pages, I use selector directive of child component.
#Component({
selector: 'child-component',
})
export class ChildComponent{
ngOnInit() {
//How to write determining code for which parent is active now?
////ParentComponent1 or ParentComponent2 ?
}
}
#Component({
selector: 'parent-component1',
})
export class ParentComponent1{
}
#Component({
selector: 'parent-component2',
})
export class Parentomponent2{
}
//How to write determining code for which parent is active now?
////ParentComponent1 or ParentComponent2 ?
Related
I need to manipulate the styling and visibility of a button that is present in one of the external library component. For better understanding below is the scenario.
parent.component.html
<child-component></child-component>
child.component.html
<external-component></external-component>
So the button is present in an external library component which I need to manipulate in the parent component.
Note: The button does not have any template reference variable and since it is present in external library I can not add it in its html.
Is there any way this can be done?
Thanks in advance :-)
In the component file add the following code
import { ElementRef } from '#angular/core';
#Component({
selector: 'app-my-contract',
templateUrl: './my.component.html',
styleUrls: ['./my-contract.component.css']
})
export class MbpContractComponent implements OnInit {
#ViewChild('myInput') myInputVariable: ElementRef
}
In your code you can use like
this.myInputVariable.nativeElement.disabled = true;
Or you can use any properties on that element
I am trying to write a directive that turns the content of a paragraph to uppercase when you hover your mouse over it. I am not getting any errors whatsoever - it just does not work. I have written a similar code before that highlights the text to a certain color, which worked. Why wouldn't it also work when changing the text to uppercase?
filter.component.html
<p appToUpperCase>String to uppercase</p>
to-upper-case.directive.ts
import { Directive, HostListener, ElementRef } from '#angular/core';
#Directive({
selector: '[appToUpperCase]'
})
export class ToUpperCaseDirective {
constructor(public el: ElementRef) {
}
#HostListener('mouseenter2') onMouseEnter() {
this.el.nativeElement.value = this.el.nativeElement.value.toUpperCase();
}
}
EDIT: As #Ilya Rachinsky suggested, I have changed the event name from mouseenter2 to mouseenter and it still does not work.
Your directive structure looks fine. I guess you forgot to include it into the list of declarations on the module, so the directive will be available for the templates. Additionally, there is no 'value' property on 'p' element, you need to use innerHTML as previously suggested.
Checkout my example: https://stackblitz.com/edit/angular-ivy-uppercase-directive?file=src%2Fapp%2Fto-upper-case.directive.ts
You have to use correct event name - mouseenter instead mouseenter2
I have a problem:
I want to get the position of an element as values. Like x= 10 and y = 30 for example. After that i want use them to update the position of the element next time. Like first of all element A was on position x=5 and y=5. Then i drag the position and get the positions x=10 and y=30. Then i'm setting the position for the next time and update the position.
Please Help!
Here is an example on Stackblitz using getBoundingClientRect() to get all the data you need, and here is the code:
.ts :
import {
Component,
ElementRef,
ViewChild,
AfterViewInit,
AfterContentChecked,
AfterViewChecked
} from "#angular/core";
/**
* #title Basic Drag&Drop
*/
#Component({
selector: "cdk-drag-drop-overview-example",
templateUrl: "cdk-drag-drop-overview-example.html",
styleUrls: ["cdk-drag-drop-overview-example.css"]
})
export class CdkDragDropOverviewExample implements AfterViewChecked {
#ViewChild("block") block: ElementRef;
constructor() {}
ngAfterViewChecked() {
let datas = this.block.nativeElement.getBoundingClientRect();
console.log("datas = ", datas);
}
onDrop(item: any) {
console.log("item = ", item.target.getBoundingClientRect());
}
}
.html :
<div class="example-box" cdkDrag #block (mouseup)="onDrop($event)">
Drag me around
</div>
.css :
.example-box {
width: 200px;
height: 200px;
border: solid 1px #ccc;
}
Note this is using cdkDrasg from Angular (I based the example from a stackblitz of the documentation) so you'll need to adapt a bit if you use something else for the drag & drop functionality.
Also, is you plan to edit the position manually (through typescript), consider using Renderer2 instead of using the ViewChild directly.
I have a component A which only contain a div with an id and a buttons that renders a component inside the div using innterHTML document.getElementById('my-router-outlet').innerHTML = '<app-component-b-page></app-component-b-page>';. But this is not rendering I wonder why?.
I'm trying to avoid using ngIf to be a selector for which component should be rendered for performance reason. Also if I clear the innerHTML does the resources of that component will be cleared?
Okay so a few things here
innerHTML = '<app-component-b-page></app-component-b-page>' is never going to work, angular wont recognise the angular component tag from a innerHTML call
using *ngIf wont affect the performance of the page, so doing the following
<app-component-b-page *ngIf="value === true"></app-component-b-page>
is probably you best option here
If you really don't want to use *ngIf you can use #ViewChild and ComponentFactoryResolver
In your HTML
<!-- this is where your component will be rendered -->
<div #entry></div>
In your component
import { Component, OnInit, ViewChild, ViewContainerRef, ComponentFactoryResolver } from '#angular/core'
import { YourComponent } from ... // import the component you want to inject
// ...
export class ...
#ViewChild('entry', {read: ViewContainerRef, static: true }) entry: ViewContainerRef;
constructor(
private _resolver: ComponentFactoryResolver
) {}
showComponent() {
const factory = this._resolver.resolveComponentFactory(YourComponent);
// this will insert your component onto the page
const component = this.entry.createComponent(factory);
}
// and if you want to dynamically remove the created component you can do this
removeComponent() {
this.entry.clear();
}
You are adding the element to the dom directly and it's not rendered by Angular.
You should go for the *ngIf.
I would like to keep web page in memory so that when I click on back button (not the one on web browser) or on a routerlink, the HTML page instantly loads if I already visit it(because I have some data to load that I don't want to be reload).
I've seen a method with tabbed interface : https://www.w3.org/Style/Examples/007/target.en.html#tab1
but it is not adapted for my code architecture.
I'm using routerlinkin angular2 to navigate threw pages and a back button calling a function on click to go to the previous page.
I try to detail as far as I can so people can understand better my code architecture and the way routerlink method works.
Back button function (works independently from routerlink) :
goBack() {
window.history.back();
}
The router link method from page 1 to page 2:
page1.html :
<a[routerLink]="['PAGE2']"> go to page 2</a>
page1.ts component:
import { Router, ROUTER_DIRECTIVES } from '#angular/router-deprecated';
#Component({
selector: 'page1',
templateUrl: 'page1.html',
styleUrls: ['page1.css'],
directives: [ROUTER_DIRECTIVES]
})
main.ts :
import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from '#angular/router-deprecated';
#Component({
providers: [ROUTER_PROVIDERS]
})
#RouteConfig([
{ path: '/page2', name: 'PAGE2', component: Page2}]) //component representing class Page2 in page2.ts
Any idea to help me manage it is welcomed, thanks by advance !
Just cache the data in the service like explained in What is the correct way to share the result of an Angular 2 Http network call in RxJs 5?
There is currently no way to prevent the router from re-creating the component when you route away and back to the component.
Well, for those having the same problem, I think the best way to manage it is to map the data into a localStorage key like this :
localStorage.setItem('favoris',JSON.stringify(my_array)); //set my data array
array = JSON.parse(localStorage.getItem('key_name')); //get in array
And then ngOnInitin the class called by the router will call the initial function depending of localStorage key being true or not.