Communication between Angular2 and Flex - apache-flex

How can I do to make a communication between flex (swf) application and angular2 application?
I know how to do with js and flex but I don't see how flex can find a angular2 method.
With JS : just need method like :
function flexUp() {
console.log('Flex Up');
}
and in flex, call the JS method :
ExternalInterface.call("flexUp");
I'm newbie in the JS/Angular2 world.

You can fire events in flex and listen to them in Angular Angular 2 - communication of typescript functions with external js libraries
or make methods from Angular components, directives, or services globally known like explained in Angular2 - how to call component function from outside the app

The good code :
In flex :
ExternalInterface.call("window.angularFlexComponent.initFlex");
In Angular2 :
In flex.d.ts :
interface Window {
angularFlexComponent: any;
}
In flex.components.ts :
import {Component, NgZone, OnDestroy} from '#angular/core';
#Component({
selector: 'flex',
templateUrl: 'app/components/flex/flex.html'
})
export class FlexComponent implements OnDestroy {
constructor(private _ngZone: NgZone) {
window.angularFlexComponent = { initFlex: this.initFlex.bind(this), zone: _ngZone };
}
initFlex(): void {
console.log('Artemis Flex Up');
}
ngOnDestroy() {
window.angularFlexComponent = null;
}
}

Related

Imported angular module doesn't work the first time a route is visited, but it works in the subsequent visits

I have a simple Loader Module hosted in a private npm repository. This module only intercepts http calls and displays a css loader. The code is simple: it has a public api that exports the module and a component. The module has an http interceptor that calls a service which sets a variable isLoading.
The component code is split into three files, as usual (ts, html and scss).
loader.component.ts
import { Component, OnInit, AfterViewInit } from '#angular/core';
import { LoaderService } from '../service/loader.service';
#Component({
selector: 'loader',
templateUrl: './loader.component.html',
styleUrls: ['./loader.component.scss']
})
export class LoaderComponent implements OnInit {
public isLoading: boolean;
constructor(private loaderService: LoaderService) { }
ngOnInit(){
this.loaderService.isLoading.subscribe(status => this.isLoading = status);
}
}
loader.component.html
<div *ngIf="isLoading" class="overlay">
<div class="loader center-block"></div>
<p class="wait">
<strong>Wait... </strong>
</p>
</div>
The loader.component.scss file defines the loader, overlay and wait css classes (not shown for brevity).
The interceptor code is here:
#Injectable()
export class LoaderInterceptor implements HttpInterceptor {
constructor(private loaderService: LoaderService) {}
intercept(
request: HttpRequest<unknown>,
next: HttpHandler
): Observable<HttpEvent<any>> {
this.loaderService.show();
return next.handle(request).pipe(finalize(() => this.loaderService.hide()));
}
}
And finally, the service code:
import { Injectable } from '#angular/core';
import { Subject } from 'rxjs';
#Injectable({
providedIn: 'root'
})
export class LoaderService {
public isLoading: Subject<boolean>;
constructor() {
this.isLoading = new Subject<boolean>();
}
show() {
this.isLoading.next(true);
}
hide() {
this.isLoading.next(false);
}
}
This module is imported at the app.module.ts of an application and declared in the imports array of the decorator.
The application has some routes with lazy load feature modules.
The loader module is used at the app.component.html file, as follows:
<loader></loader>
<router-outlet></router-outlet>
The problem: the loader does not work the first time we visit a route, but it works if we click the previous button at the browser or we click to go back to homepage or any other way I tested visiting a route twice or more. Otherwise, it doesn't work.
I tried to find similar questions, I tried to see the order of css imports, I also tried to analise the loader module, the import order, but no clue about what is happening.

How to add a class to the body when ever navigate to a particular component or when ever refresh It?

Problem:
I have built an angular application. There I want to add a CSS class to the body whenever It navigates to that components and remove it whenever the user leaves out of that component.
This is what I have done. In the global CSS file, I have defined a style like this.
.background-color {
background-image: linear-gradient(to right,#3f51b5, #00bcd4) !important;
}
And In the login component, I have done something like this.
import { Component, OnInit } from "#angular/core";
#Component({
selector: "app-login",
templateUrl: "./login.component.html",
styleUrls: ["./login.component.css"]
})
export class LoginComponent implements OnInit {
constructor() {
}
ngOnInit() {
window.onload = function() {
document.body.classList.add("background-color");
};
}
}
But this is not working correctly. When I navigate to this component the styles not added but when I refresh the pages it adds the styling to the body. I tried a lot to find a solution to this problem but I was unable to do so. Can someone help me to solve this issue? Thank you!
No need to write onLoad function inside the ngOnInit() method. I suggest you read the angular official ngOnit().
rewrite your ngOnInit() like below
ngOnInit() {
let element = document.getElementById("bg-color");
element.classList.add("background-color");
}
and your component.html file
<p id="bg-color">
Start editing to see some magic happen :)
</p>
Live Demo
Since you are using angular routing, this will not work unless you navigate to that component manually, because when you navigate to a router link, it does not reload the application, it justs removes the other components and add the new component. It does not trigger the onLoad event. But when you reload manually, it will work.
try the following
export class LoginComponent implements OnInit {
loaded: boolean = false;
constructor() {
}
ngOnInit() {
this.loaded = true;
}
and on the component html
<body [class.background-color]="loaded"></body>
or something on the similar lines.

Attach event to all elements with a specific class

I would like to attach an event listner in my component that will fire for all elements that have a specific class.
These are generated by a third party component so i cannot attach it at the point where they are created.
i would like to do effectively do the equivalent of the following jquery statement but in angular where .day is the class.
$(document).on('mousedown','.day',function(jsEvent){
});
Thanks
You can use a Directive to attach the listener:
import { Directive, HostListener } from '#angular/core';
#Directive({
selector: '.day'
})
export class DayDirective {
#HostListener('mousedown', ['$event'])
yourFunction(event: Event): void { ... }
}
To wire up the Directive, you add it to the module that requires it. This could be your app module, a shared module or a feature module.
import { NgModule } from '#angular/core';
#NgModule({
declarations: [
DayDirective,
],
...
})
export class YourModule {}

Angular Dynamic Components - Add Class and other attributes

I am using the following code for creating the dynamic components
import {
Component, OnInit, ViewContainerRef, ViewChild, ViewChildren,
ReflectiveInjector, ComponentFactoryResolver, ViewEncapsulation, QueryList, Input, AfterViewInit
} from '#angular/core';
import { Router, ActivatedRoute } from '#angular/router';
import { forEach } from '#angular/router/src/utils/collection';
import { IComponent } from 'app/app.icomponent';
#Component({
encapsulation: ViewEncapsulation.None,
selector: 'dynamic-component',
entryComponents: [HomeComponent, HighlevelSignalComponent],
template: `
<div #dynamicDiv [ngClass]="classFromMenu" >
<ng-template #dynamicComponentContainer></ng-template>
</div>
`,
styleUrls: [
'./dynamic-content.component.css'
],
})
export class DynamicComponent implements IComponent, OnInit, AfterViewInit {
classFromMenu: any;
#ViewChild('dynamicComponentContainer', { read: ViewContainerRef }) dynamicComponentContainer: ViewContainerRef;
constructor(private resolver: ComponentFactoryResolver, private route: Router,
private activatedRoute: ActivatedRoute, ) {
}
.......
buildComponent(passedData) {
// orderAndObjs has the data for creating the component
this.orderAndObjs.forEach(obj => {
var componentFactory = this.resolver.resolveComponentFactory(obj.component);
var compRef = this.dynamicComponentContainer.createComponent(componentFactory);
// compRef is the component that is created.
//Assuming the component that i am trying to create is <dynamic-component>.
//I want to add either a class or any other attribute like this
//<dynamic-component class="flex">
});
}
}
}
The dynamic-component is created perfectly fine and everything is working as expected. But the only issue is I want to add a class for dynamic-component so that it can be
<dynamic-component class="dynamicClass">
Any help is appreciated :(
Hmm.. I usually add it to the selector of component that is supposed to be an entryComponent ...
selector: 'dynamic-component.someclass',
^^^^^^^^^^^
to add attribute use attribute selector:
selector: 'dynamic-component[myattr=value]',
I call it hidden feature of entryComponents
but its declarative approach and can't be changed at runtime(indeed we can change it)
In Angular 5/6, using Renderer2 from #angular/core, you can do something like below:
constructor(private resolver: ComponentFactoryResolver, private route: Router,
private activatedRoute: ActivatedRoute, private renderer2: Renderer2) {
}
buildComponent(passedData) {
this.orderAndObjs.forEach(obj => {
var componentFactory = this.resolver.resolveComponentFactory(obj.component);
var compRef = this.dynamicComponentContainer.createComponent(componentFactory);
this.renderer2.addClass(compRef.location.nativeElement, 'flex');
});
}
High-level DOM operations are performed with Renderer2 provider. Considering that it was injected, it is:
this.renderer2.addClass(compRef.location.nativeElement, 'dynamicClass');
It should be noticed that depending on how dynamic element is attached to DOM, this may be unnecessary complication.
Considering that dynamicComponentContainer is real DOM element and not <ng-template>, the view of dynamic component can be directly mounted to the container, thus eliminating <dynamic-component> wrapper element:
Given the container:
<div class="dynamicClass" #dynamicComponentContainer></div>
It will be:
var compRef = componentFactory.create(
this.injector,
[],
this.dynamicComponentContainer.element.nativeElement
);

Why is Mounting methods not working in reactjs.net when I write on JSX

I'm a noob and I'm trying to compile a JSX following this tutorial :
http://xabikos.com/2015/03/18/Using-Reactjs-net-in-Web-Forms/
using reactjs.net
I'm trying to define a class like this...
class First extends React.createClass {
render(){
}
constructor(props) {
}
componentDidMount() {
}
}
Render method seems to work fine, but componentDidMount is not called,
and the constructor is also never called, any idea why is this happening?
You Are mixing The concept of function based components and class-based components, You can not use createClass while using class-based Components, That's why you are not getting what you desire.
The right way to make a component using class is this:-
import React from 'react';
class First extends React.Component{
constructor(props) {
super(props);
}
componentDidMount() {
}
render(){
}
}
And When You have to make components Using plain functions You have to use this:-
var First = React.createClass({
render:function(){
//Your view
}
})
I Hope it will solve your problem

Resources