web-dev-qa-db-fra.com

Quel est l'équivalent d'une usine dans Angular2?

Je suis donc habitué à utiliser des usines et des services dans Angular.

Je lis les documents Angular2 et je ne vois pas d’équivalent d’une usine. Quel est l'équivalent pour Angular2?

11
user2202911

Les usines, les services, les constantes et les valeurs disparaissent dans Angular2. Angular2 est radicalement et fondamentalement différent du classique Angular. Dans Angular2, les concepts de base sont

  • composants
  • injection de dépendance
  • contraignant

La notion de services, d’usines, de fournisseurs et de constantes a été critiquée dans Angular 1. Il était difficile d’en choisir un. Les supprimer simplifie un peu les choses.

Dans l’angulaire original, vous définiriez un service comme suit

app.service('BookService', ['$http', '$q', BookService]);
function BookService($http, $q){
  var self = this;
  var cachedBooks;
  self.getBooks = function(){
    if (cachedBooks) {
      return $q.when(cachedBooks);
    }
    return $http.get('/books').then(function(response){
      cachedBooks = response.data.books;
      return cachedBooks;
    })
  }
}

Angular2 utilise considérablement la syntaxe ES6 pour rendre le code plus lisible et plus facile à comprendre.

Un nouveau mot clé dans ES6 est class, qui peut être considéré comme un service.

Les classes ES6 sont un simple sucre par rapport au modèle OO basé sur un prototype. Le fait de disposer d’un seul formulaire déclaratif pratique facilite l’utilisation des modèles de classe et encourage l’interopérabilité. Les classes prennent en charge l'héritage, les super appels, les méthodes d'instance, les méthodes statiques et les constructeurs basés sur des prototypes.

Voici à quoi ce code pourrait ressembler dans Angular2

import {HttpService, Promise}  from '../Angular/Angular2';
export class BookService{
    $http, $q, cachedBooks;
    constructor($http: HttpService, $q: Promise) {
        this.$http = $http;
        this.$q = $q
    }
    getBooks() {
    if (this.cachedBooks) {
        return this.$q.when(this.cachedBooks);
    }
    return this.$http.get('/books').then(function(data) {
        this.cachedBooks = data.books;
        return this.cachedBooks;
    })
  }
}
14
Richard Hamilton

La réponse de @Richard Hamilton est appréciée et, en plus, il y a peu de points à noter.

Pour Usines, Service, etc., dans Angular2, nous avons service (ou service partagé). nous devons rendre notre service Injectable pour pouvoir l'utiliser.

REMARQUE: Ce code appartient à la version bêta et non à la version RC.

import {Component, Injectable,Input,Output,EventEmitter} from 'angular2/core'
import {Router} from 'angular2/router';
import {Http} from 'angular2/http';

export interface ImyInterface {
   show:boolean;
}

@Injectable()      <---------------------------- Very Important
export class sharedService {  <----------------- Service Name
  showhide:ImyInterface={show:true};

  constructor(http:Http;router:Router)
  {
    this.http=http;
  }     
  change(){
        this.showhide.show=!this.showhide.show;
  }
} 

Si je veux utiliser partout dans mon application, alors je dois injecter ce service dans la fonction bootstrap comme ça,

bootstrap(App, [HTTP_PROVIDERS,sharedService    <--------Name Injection
      ROUTER_PROVIDERS,bind(APP_BASE_HREF).toValue(location.pathname)
]);

De cette façon, il crée une instance unique de votre service. Si vous ne voulez pas utiliser une seule instance, vous pouvez utiliser les métadonnées Providers:[sharedService] dans votre décorateur @component.

Ensuite, utilisez-le dans l'un de vos composants,

export class TheContent {
  constructor(private ss: sharedService) {  <--------Injection dependency of your newly created service
    console.log("content started");
  }
  showhide() {
    this.ss.change();  <----- usage
  }
}

Consultez l'exemple de travail ici

14
micronyks

Je ne sais pas ce que les usines font exactement dans Angular1 mais dans Angular2, il y a useFactory:

{ 
  provide: SomeClass, 
  useFactory: (dep1, dep2) => (x) => new SomeClassImpl(x, dep1, dep2),
  deps: [Dep1, Dep2]
}

pour fournir votre propre logique de construction d'instance si la valeur par défaut ne correspond pas à vos besoins.

Vous pouvez également injecter une fabrique pour créer vous-même de nouvelles instances:

/* deprecated or removed depending on the Angular version you are using */
provide(SomeClass, {
    useFactory: (dep1, dep2) => {
        (x) => new SomeClassImpl(x, dep1, dep2), 
    },
    deps: [Dep1, Dep2]
})
constructor(@Inject(SomeClass) someClassFactory: any) {
  let newSomeClass = someClassFactory(1);
}

L'argument x doit avoir une affectation de type, sinon angular ne sait pas le traiter.

class SomeClassImpl {
  constructor(x: number, dep1: Dep1, dep2: Dep2){}
}
7

Si vous avez besoin d'une nouvelle instance d'un service dans un composant, vous devez la fournir dans ce composant comme ceci:

@Component({
  selector:    'hero-list',
  templateUrl: './hero-list.component.html',
  providers:  [ HeroService ]
})

Cela générera une nouvelle instance de HereService comme le ferait une fabrique.

1
Damsorian