ProductPromotion
Logo

Angular.JS

made by https://0x3d.site

GitHub - nigrosimone/ng-portal: Component property connection in Angular application wherever they are.
Component property connection in Angular application wherever they are. - nigrosimone/ng-portal
Visit Site

GitHub - nigrosimone/ng-portal: Component property connection in Angular application wherever they are.

GitHub - nigrosimone/ng-portal: Component property connection in Angular application wherever they are.

NgPortal Build Status Coverage Status NPM version

Component property connection in Angular application wherever they are.

Description

Sometime there is a need to send data beetween components. A common pattern in Angular is sharing data between a parent component and one or more child components by using the @Input() and @Output() directives. This pattern works if component are in the same scope. In this example an output component set a property value imputed by input component, eg:

import { Component } from '@angular/core';

@Component({
  selector: 'app-component',
  template: `<app-output (event)="value = $event"><app-output>
             <app-input [value]="value"></app-input>`,
})
export class AppComponent {
  value: string;
}

But what happen if both component arent in the same scope? A common pattern in this case is propagate @Input() and @Output() throught the tree of parents/childs component or write a shared service for exhange the data.

NgPortal offer a dead simple solution, a new directive @NgPortal() that connect two property wherever they are.

In this example every property called value with @NgPortal() directive is connected and every changes is propagated wherever, eg.:

import { Component } from '@angular/core';
import { ngPortalInput, ngPortalOutput } from 'ng-portal';

@Component({
  selector: 'app-input',
  template: `<input (keyup)="value = $event.target['value']">`,
})
export class InputComponent {
  @ngPortalInput() value: string;
}

@Component({
  selector: 'app-output',
  template: `{{ value | async }}`,
})
export class OutputComponent {
  @ngPortalOutput() value: Observable<string>;
}

There are also mono-directional directive @NgPortalInput() and @NgPortalOutput() for more control.

See the stackblitz demo.

Features

✅ Two way data binging ✅ Mono directional communication ✅ Async pipe support ✅ NgModel support

Get Started

Step 1: install ng-portal

npm i ng-portal

Step 2: Import NgPortalModule into your app module, eg.:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';

import { NgPortalModule } from 'ng-portal';

@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    NgPortalModule,
  ],
  providers: [],
  bootstrap: [AppComponent],
  ],
})
export class AppModule { }

API

Available property decorators (options is optional):

  • @ngPortal(options?: NgPortalDecoratorOptions): two way communication
  • @ngPortalInput(options?: NgPortalDecoratorOptions): only send changes
  • @ngPortalOutput(options?: NgPortalDecoratorOptions): only receive changes

Decorator options interface:

export interface NgPortalDecoratorOptions {
  key: string;
}

From default ngPortal use property name as the key:

@ngPortal() value: string;

is equivalent to:

@ngPortal({key: 'value'}) value: string;

and is also equivalent to:

@ngPortal({key: 'value'}) whateverYouWant: string;

Communication ways:

  • @ngPortal() sends to @ngPortal() and @ngPortalOutput()
  • @ngPortal() receives from @ngPortal() and @ngPortalInput()
  • @ngPortalInput() sends to @ngPortal() and @ngPortalOutput()
  • @ngPortalInput() doesn't receive
  • @ngPortalOutput() doesn't send
  • @ngPortalOutput() receives from @ngPortal() and @ngPortalInput()

Type:

Behind the scene, @ngPortal() apply a getter and a setter on the property:

  • @ngPortal() property: string; => get property(): Observable<string> and set property(value: string): void
  • @ngPortalInput() property: string; => set property(value: string): void (only setter available)
  • @ngPortalOutput() property: string; => get property(): Observable<string> (only getter available)

Examples

Below there are some examples of use case.

Example: input / output components connected by property name

InputComponent has property value with @ngPortalInput() decorator that on change update property value into OutputComponent with @ngPortalOutput(), eg.:

import { Component } from '@angular/core';
import { ngPortalInput, ngPortalOutput } from 'ng-portal';
import { Observable } from 'rxjs';

@Component({
  selector: 'app-input',
  template: `<input (keyup)="value = $event.target.value">`,
})
export class InputComponent {
  @ngPortalInput() value: string;
}

@Component({
  selector: 'app-output',
  template: `{{ value | async }}`,
})
export class OutputComponent {
  @ngPortalOutput() value: Observable<string>;
}

Example: input / output components connected by key

InputComponent has property inputValue with @ngPortalInput({key: 'foo'}) decorator that on change update property outputValue into OutputComponent with @ngPortalOutput({key: 'foo'}). In this case is the key 'foo' that made the connection, eg.:

import { Component } from '@angular/core';
import { ngPortalInput, ngPortalOutput } from 'ng-portal';
import { Observable } from 'rxjs';

@Component({
  selector: 'app-input',
  template: `<input (keyup)="inputValue = $event.target.value">`,
})
export class InputComponent {
  @ngPortalInput({key: 'foo'}) inputValue: string;
}

@Component({
  selector: 'app-output',
  template: `{{ value | async }}`,
})
export class OutputComponent {
  @ngPortalOutput({key: 'foo'}) outputValue: Observable<string>;
}

Example: NgModel connection by property name

ModelComponent has property model with @ngPortal() decorator that on change update property model in every components with same property and @ngPortal() or @ngPortalOutput() decorators. eg.:

import { Component } from '@angular/core';
import { ngPortal } from 'ng-portal';

@Component({
  selector: 'app-model',
  template: `<input [ngModel]="model | async" (ngModelChange)="model = $event">`,
})
export class ModelComponent {
  @ngPortal() model: any;
}

Example: NgModel connection connected by key

ModelComponent has property model with @ngPortal({key: 'foo'}) decorator that on change update every property in every components with @ngPortal({key: 'foo'}) or @ngPortalOutput({key: 'foo'}) decorators. eg.:

import { Component } from '@angular/core';
import { ngPortal, ngPortalOutput } from 'ng-portal';
import { Observable } from 'rxjs';

@Component({
  selector: 'app-model',
  template: `<input [ngModel]="model | async" (ngModelChange)="model = $event">`,
})
export class ModelComponent {
  @ngPortal({key: 'foo'}) model: any;
}

@Component({
  selector: 'app-output',
  template: `{{ value | async }}`,
})
export class OutputComponent {
  @ngPortalOutput({key: 'foo'}) outputValue: Observable<string>;
}

Service

You can inject into your component the NgPortalService that expose some utils methods:

export class NgPortalService {

  /**
   * Send a "value" for the "key" (key or property name)
   */
  send(key: string, value: any): void;

  /**
   * Return an Observable for the "key" (key or property name)
   */
  get<K>(key: string): Observable<K>;

  /**
   * Return an Observable for all the "key" (key or property name)
   */
  getAll(): Observable<NgPortalServiceMessage>;
}

Support

This is an open-source project. Star this repository, if you like it, or even donate. Thank you so much!

My other libraries

I have published some other Angular libraries, take a look:

More Resources
to explore the angular.

mail [email protected] to add your project or resources here 🔥.

Related Articles
to learn about angular.

FAQ's
to learn more about Angular JS.

mail [email protected] to add more queries here 🔍.

More Sites
to check out once you're finished browsing here.

0x3d
https://www.0x3d.site/
0x3d is designed for aggregating information.
NodeJS
https://nodejs.0x3d.site/
NodeJS Online Directory
Cross Platform
https://cross-platform.0x3d.site/
Cross Platform Online Directory
Open Source
https://open-source.0x3d.site/
Open Source Online Directory
Analytics
https://analytics.0x3d.site/
Analytics Online Directory
JavaScript
https://javascript.0x3d.site/
JavaScript Online Directory
GoLang
https://golang.0x3d.site/
GoLang Online Directory
Python
https://python.0x3d.site/
Python Online Directory
Swift
https://swift.0x3d.site/
Swift Online Directory
Rust
https://rust.0x3d.site/
Rust Online Directory
Scala
https://scala.0x3d.site/
Scala Online Directory
Ruby
https://ruby.0x3d.site/
Ruby Online Directory
Clojure
https://clojure.0x3d.site/
Clojure Online Directory
Elixir
https://elixir.0x3d.site/
Elixir Online Directory
Elm
https://elm.0x3d.site/
Elm Online Directory
Lua
https://lua.0x3d.site/
Lua Online Directory
C Programming
https://c-programming.0x3d.site/
C Programming Online Directory
C++ Programming
https://cpp-programming.0x3d.site/
C++ Programming Online Directory
R Programming
https://r-programming.0x3d.site/
R Programming Online Directory
Perl
https://perl.0x3d.site/
Perl Online Directory
Java
https://java.0x3d.site/
Java Online Directory
Kotlin
https://kotlin.0x3d.site/
Kotlin Online Directory
PHP
https://php.0x3d.site/
PHP Online Directory
React JS
https://react.0x3d.site/
React JS Online Directory
Angular
https://angular.0x3d.site/
Angular JS Online Directory