簡體   English   中英

在課堂上與Angular 2一起使用服務

[英]Use service in class with Angular 2

我想在班級(模型)中使用服務

在我班上使用服務

電影list.component.ts

import { Component, OnInit } from '@angular/core';
import {Movie} from "../../models/movie";
import {MovieService} from "../../services/movie.service";

@Component({
  selector: 'movie-list',
  templateUrl: './movie-list.component.html',
})

export class MovieListComponent implements OnInit {
  public movies = [];
  public movie: Movie;

  constructor(private movieService: MovieService) {
      this.movie = new Movie();
  }

  ngOnInit() {
    console.log(this.movie.getMovies());
    this.movies = movie.getMovies();
  }
}

電影list.component.html

<div *ngFor="let movie of movies">
    {{ movie.title }}

    <div *ngFor="let actor of movie.actors">
        {{ actor.name }} - {{ actor.getOscar() }}
    </div>
</div>

movie.ts(電影模型)

import { Actor } from "./actor";

export class Movie {

    constructor(title: string = '', actors: any = []) {
        this.title = title;
        this.actors = [];
    }

    title: string = '';
    actors: any = [];
    movieService;

    setModel(obj) {
        Object.assign(this, obj);
    }

    addActor(actor) {
        this.actors.push(actor);
    }

    build(data) {
        let movie = new Movie(
            data.title,
            data.actors
        );

        movie.setModel({ actors: []});

        data.actors.forEach((actor) => {
            let new_actor = new Actor(
                actor.firstname,
                actor.lastname
            );

            movie.addActor(new_actor);
        });

        return movie;
    }

    getMovies() {
        let movies: any[];

        this.movieService.getMovies().subscribe(
            data => {
                data.map((result) => {
                    movies.push(this.build(result));
                });

                return movies;
            },
            error => {
                console.error(error);
            }
        )
    }
}

actor.ts(演員模型)

export class Actor {

    constructor(firstname: string, lastname: string) {
        this.firstname = firstname;
        this.lastname = lastname;
    }

    firstname: string;
    lastname: string;

    setModel(obj) {
        Object.assign(this, obj);
    }

    getOscar() {
        return '10 oscars';
    };
}

movie.service.ts

import { Injectable } from '@angular/core';
import {Http} from "@angular/http";
import 'rxjs/add/operator/map';

@Injectable()
export class MovieService {
  constructor(private http:Http) { }

    getMovies() {
    return this.http
        .get('data/movies.json')
        .map(res => res.json());
  }

}

movies.json

[
  {
    "title": "title1",
    "actors": [
      {
        "firstname": "firstname10",
        "lastname": "lastname10"
      },
      {
        "firstname": "firstname11",
        "lastname": "lastname11"
      }
    ]
  },
  {
    "title": "title2",
    "actors": [
      {
        "firstname": "firstname20",
        "lastname": "lastname20"
      },
      {
        "firstname": "firstname21",
        "lastname": "lastname21"
      }
    ]
  }
]

我想在班級中“注入/使用”我的服務以使用此工作流程:

  1. 組件(在我的班級中調用getMovies)
  2. 類(在我的服務中調用getMovies,帶有響應)使用this.build構建我的對象(Movie,Actor)
  3. 服務(調用我的API,返回JSON,不包含類型對象(電影,演員)

我試圖在類中使用@inject,但是這篇文章不起作用如何將Service注入類(不是組件)

我想知道最佳做法。

有了這段代碼,我有一個錯誤:

在此處輸入圖片說明

修改

在我的組件中添加了這個:

constructor(private movieService: MovieService) {
  this.movie = new Movie();
  this.movie.movieService = movieService; // add this line
}

我的組件在此行上有一個錯誤:

ngOnInit() {
    console.log(this.movie.getMovies());
    this.movies = movie.getMovies(); // error Type 'void' is not assignable to type 'any[]'.
}

我想保留模型中的訂閱,以便在我的組件中使用干凈的代碼

在此處輸入圖片說明

解決了

電影list.component.ts

import { Component, OnInit } from '@angular/core';
import { Movie } from "../../models/movie";
import { MovieService } from "../../services/movie.service";

@Component({
  selector: 'movie-list',
  templateUrl: './movie-list.component.html',
})

export class MovieListComponent implements OnInit {
    public movie: Movie;
    public movies = [];

  constructor(private movieService: MovieService) {
      this.movie = new Movie('', []);
      this.movie.movieService = movieService;
  }

  ngOnInit() {
      this.movies = this.movie.getMovies();
  }
}

movie.ts

import { MovieService } from "../services/movie.service";
import { Actor } from "./actor";

export class Movie {

    constructor(
        private title: string = '',
        private actors: any[] = [],
    ) { }

    public movieService : MovieService;

    setModel(obj) {
        Object.assign(this, obj);
    }

    addActor(actor) {
        this.actors.push(actor);
    }

    build(data) {
        const movie = new Movie(
            data.title,
            data.actors,
        );

        movie.setModel({ actors: [] });

        data.actors.forEach((actor) => {
            const new_actor = new Actor(
                actor.firstname,
                actor.lastname
            );

            movie.addActor(new_actor);
        });

        return movie;
    }

    getMovies() {
        let movies = [];

         this.movieService.getMovies().subscribe(
            data => {
                data.map((result) => {
                    movies.push(this.build(result));
                });
            },
            error => {
                console.error(error);
            }
        );

        return movies;
    }
}

您應該閱讀有關SmartPresentation (啞)組件的信息。 到目前為止,這是最佳做法,因為整個角度數據管理和檢測更改都圍繞着它進行。

http://blog.angular-university.io/angular-2-smart-components-vs-presentation-components-whats-the-difference-when-to-use-each-and-why/


您的錯誤來自您在構造函數中設置的兩個參數,因為這兩個參數應該由@Input裝飾器發送或從服務中獲取。 您不會做let foo = new MovieComponent(.., ...);類的事情let foo = new MovieComponent(.., ...); 所以這行不通

請從官方文檔中閱讀。 它還將幫助您設置智能/啞組件結構:

https://angular.io/guide/component-interaction#pass-data-from-parent-to-child-with-input-binding

編輯:要使您的服務正常工作,只需將其作為依賴項傳遞給MovieComponent構造函數即可:

constructor(
  private movieService: MovieService
) {}

不要忘記提供您MovieService在你(我希望) MovieModule或其它地方的MovieComponent聲明(在同一模塊中)


EDIT2:這是為我工作的代碼部分。 需要重新設計模型類,並使用一種方法來發回異步生成的影片,但是即使那樣,我仍會發現該模型不是很有用。 您最好只使用接口和服務。 此外,這顯然不是智能/啞組件交互,因此需要一些升級才能實現您想要的功能。

MovieListComponent

export class MovieListComponent implements OnInit {
  public movies = [];
  public movie: Movie;

  constructor(private movieService: MovieService) {
    this.movie = new Movie('', []);
  }

  ngOnInit() {
    this.movie.movieService = this.movieService;
    this.movie.getMovies().subscribe(
      data => {
        data.map((result) => {
          this.movies.push(this.movie.build(result));
        });
      }
    );
  }
}

電影(模特)

export class Movie {
  movies: any[];
  movieService: MovieService

  constructor(
    private title: string = '',
    private actors: any[] = [],
  ) { }

  setModel(obj) {
    Object.assign(this, obj);
  }

  addActor(actor) {
    this.actors.push(actor);
  }

  build(data) {
    const movie = new Movie(
      data.title,
      data.actors,
    );

    movie.setModel({ actors: [] });

    data.actors.forEach((actor) => {
      const new_actor = new Actor(
        actor.firstname,
        actor.lastname
      );

      movie.addActor(new_actor);
    });

    return movie;
  }

  getMovies() {
    return this.movieService.getMovies();
  }
}

@NgModule({
  imports: [
    HttpModule,
    CommonModule
  ],
  declarations: [
    MovieListComponent
  ],
  providers: [
    MovieService
  ]
})
export class MainModule { }

通過提供他們的父注射器

constructor( parentInjector:Injector ){

  let injector = ReflectiveInjector.resolveAndCreate ( [ ProductService ] );

  this.productService = injector.get(ProductService, parentInjector);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM