使用Angular 2中的服务

时间:2017-08-30 09:18:24

标签: angular typescript service

我想在班级(模型)中使用服务

在我的班级中使用服务

电影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"
      }
    ]
  }
]

我想&#34;注入/使用&#34;我的班级服务使用此工作流程:

  1. 组件(在我的班级中调用getMovies)
  2. Class(在我的服务中调用getMovies,使用this.build响应构建我的对象(Movie,Actor)
  3. 服务(调用我的API,返回JSON,不带类型对象(电影,演员)
  4. 我尝试在我的课程中使用@inject,但它不适用于此帖How to inject Service into class(not component)

    我想知道这样做的最佳做法。

    使用此代码,我有一个错误:

    enter image description here

      

    修改

    在我的组件中添加了这个:

    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[]'.
    }
    

    我想保留模型中的订阅,以便在我的组件中有一个干净的代码

    enter image description here

      

    解决

    电影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;
        }
    }
    

2 个答案:

答案 0 :(得分:1)

您应该阅读有关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(.., ...);这样的事情,所以这不起作用。

请阅读官方文档中的内容。它还可以帮助您设置智能/哑元组件结构:

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 { }

答案 1 :(得分:-1)

通过提供它们的父注入器

@if($shouldShow)