Home

Awesome

⚠️ IMPORTANT

THIS REPO / PACKAGE HAS BEEN DEPRECATED

Please use new @angular-extensions/modelpackage / repo which is a combination of both the model library and related schematics which renders this package uselsess. On the other hand, feel free to keep using ngx-model if it suits your needs, it will not be deleted, but there will be no further development. Please, have a look into migration section in the new documentation.

The Angular Model - ngx-model

by @tomastrajan

npm npm npm Build Status Twitter Follow

Simple state management with minimalistic API, one way data flow, multiple model support and immutable data exposed as RxJS Observable.

Documentation

ngx-model dataflow diagram

Getting started

  1. Install ngx-model

    npm install --save ngx-model
    

    or

    yarn add ngx-model
    
  2. Import and use NgxModelModule in you AppModule (or CoreModule)

    import { NgxModelModule } from 'ngx-model';
        
    @NgModule({
      imports: [
        NgxModelModule
      ]
    })
    export class CoreModule {}
    
    
  3. Import and use Model and ModelFactory in your own services.

    import { Injectable } from '@angular/core';
    import { Observable } from 'rxjs';
    import { ModelFactory, Model } from 'ngx-model';
        
    @Injectable()
    export class TodosService {
            
      private model: Model<Todo[]>;
      
      todos$: Observable<Todo[]>;
            
      constructor(private modelFactory: ModelFactory<Todo[]>) {
        this.model = this.modelFactory.create([]); // create model and pass initial data
        this.todos$ = this.model.data$; // expose model data as named public property
      }
        
      toggleTodo(id: string) {
        // retrieve raw model data
        const todos = this.model.get();
            
        // mutate model data
        todos.forEach(t => {
          if (t.id === id) {
            t.done = !t.done;
          }
        });
            
        // set new model data (after mutation)
        this.model.set(todos);
      }
        
    }
    
  4. Use service in your component. Import and inject service into components constructor. Subscribe to services data in template todosService.todos$ | async or explicitly this.todosService.todos$.subscribe(todos => { /* ... */ })

    import { Component, OnInit, OnDestroy } from '@angular/core';
    import { Subject } from 'rxjs';
    
    import { TodosService, Todo } from './todos.service';
    
    @Component({
      selector: 'ngx-model-todos',
      templateUrl: `
        /* ... */
        <h1>Todos ({{count}})</h1>
        <ul>
          <!-- template subscription to todos using async pipe -->
          <li *ngFor="let todo of todosService.todos$ | async" (click)="onTodoClick(todo)">
            {{todo.name}}
          </li>
        </ul>
      `,
    })
    export class TodosComponent implements OnInit, OnDestroy {
    
      private unsubscribe$: Subject<void> = new Subject<void>();
      
      count: number;
     
      constructor(public todosService: TodosService) {}
    
      ngOnInit() {
        // explicit subscription to todos to get count
        this.todosService.todos
          .pipe(
            takeUntil(this.unsubscribe$) // declarative unsubscription
          )
          .subscribe(todos => this.count = todos.length);
      }
      
      ngOnDestroy(): void {
        // for declarative unsubscription
        this.unsubscribe$.next();
        this.unsubscribe$.complete();
      }
    
      onTodoClick(todo: Todo) {
        this.todosService.toggleTodo(todo.id);
      }
    
    }
    
    

Available Model Factories

Models are created using model factory as shown in above example this.model = this.modelFactory.create([]);. Multiple model factories are provided out of the box to support different use cases:

Relationship to Angular Model Pattern

This is a library version of Angular Model Pattern. All the original examples and documentation are still valid. The only difference is that you can install ngx-model from npm instead of having to copy model pattern implementation to your project manually.

Check out the Blog Post and Advanced Usage Patterns for more how-tos and examples.

Getting started with Schematics

  1. make sure you're using this in project generated with Angular CLI.
  2. install dependency with npm i -D @angular-extensions/schematics
  3. generate model services with ng g @angular-extensions/schematics:model --name path/my-model
  4. or with ng g @angular-extensions/schematics:model --name path/my-model-collection --items form model of collection of items
  5. add your own model service methods and tests

Generating model using schematics