Last active
February 13, 2017 05:57
-
-
Save dennishn/98650d9cfc938f73edb1eb06401abc32 to your computer and use it in GitHub Desktop.
Emil Møller and Dennis Haulund Nielsen's amazing DRY, SOC data modelling concept for Angular
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
I am the base Service, any business specific service will extend upon me. | |
My purpose is to control generic things, common for all services. | |
For instance i keep track of when a service is communicating with a server. | |
*/ | |
class BaseService { | |
public isSending$: Observable<any>; | |
public isSendingSubject = new Subject<any>(); | |
constructor() { | |
this.isSending$ = this.isSendingSubject.asObservable(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
I control communication with servers. I could use Apollo, XHR, WebSockets and anything else. | |
My purpose is to control asyncronus tasks. | |
*/ | |
export class DataBackend { | |
constructor() {} | |
public post(payload): Promise<any> { | |
return new Promise((resolve, reject) => { | |
setTimeout(() => { | |
resolve(true); | |
}, 1000); | |
}); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
I control the data integrity and business logic. | |
My purpose is expose an interface for a specific business model, and a business model class. | |
The business model also has responsibility of exposing a FormGroup (or FormArray, or FormControl) | |
*/ | |
import {FormGroup} from "@angular/forms"; | |
import {FormControl} from "@angular/forms"; | |
import {Validators} from "@angular/forms"; | |
export interface IData { | |
name?: string; | |
} | |
export class Data implements IData { | |
public name: string; | |
constructor( | |
name?: string | |
) { | |
this.name = name; | |
} | |
} | |
export class DataModel { | |
public form: FormGroup; | |
public internalModelData: IData; | |
constructor(name?: string) { | |
this.internalModelData = new Data( | |
name | |
); | |
this.form = new FormGroup({ | |
name: new FormControl(this.internalModelData.name || null, Validators.required) | |
}); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
I am the Injectable Service that Components will integrate with. | |
My purpose is combine the Model and Backend layers and expose a common API that makes use of these layers. | |
*/ | |
import {Injectable} from "@angular/core"; | |
import {Observable} from "rxjs"; | |
import {Subject} from "rxjs"; | |
import {DataBackend} from './data.backend'; | |
import {IData, DataModel} from './data.model'; | |
import {BaseService} from './base.service'; | |
@Injectable() | |
export class DataService extends BaseService { | |
public dataModel: DataModel; | |
private dataBackend: DataBackend; | |
constructor(name?: string) { | |
super(); | |
this.dataModel = new DataModel(name); | |
this.dataBackend = new DataBackend(); | |
} | |
public submit() { | |
this.isSendingSubject.next(true); | |
return this.dataBackend.post(this.dataModel.form.getRawValue()).then( | |
(res) => { | |
this.isSendingSubject.next(false); | |
return res; | |
} | |
); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This is just snippets from the component we used to test the implementation against. | |
public dataSvc: DataService; | |
public isSubmitting: boolean = false; | |
## In the Constructor | |
this.dataSvc = new DataService(...data...); | |
## In ng OnInit | |
this.dataSvc.isSending$.subscribe( | |
(res) => { | |
console.log('obs', res); | |
this.isSubmitting = res; | |
} | |
); | |
## A method for the template to call | |
public submit() { | |
this.dataSvc.submit().then( | |
res => console.log('Data Received!', res) | |
); | |
} | |
## In the template | |
<form [formGroup]="dataSvc.dataModel.form" (ngSubmit)="submit()" novalidate> | |
<input formControlName="name" type="text"> | |
<button class="button" [disabled]="!dataSvc.dataModel.form.valid" type="submit">SUBMIT</button> | |
</form> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment