TypeScript를 사용하여 Angular 2 구성 요소에서 모델 클래스를 어떻게 선언합니까?


82

저는 Angular 2와 TypeScript를 처음 접했고 모범 사례를 따르려고 노력하고 있습니다.

간단한 JavaScript 모델 ({})을 사용하는 대신 TypeScript 클래스를 만들려고합니다.

그러나 Angular 2는 그것을 좋아하지 않는 것 같습니다.

내 코드는 다음과 같습니다.

import { Component, Input } from "@angular/core";

@Component({
    selector: "testWidget",
    template: "<div>This is a test and {{model.param1}} is my param.</div>"
})

export class testWidget {
    constructor(private model: Model) {}
}

class Model {
    param1: string;
}

그리고 나는 그것을 다음과 같이 사용하고 있습니다.

import { testWidget} from "lib/testWidget";

@Component({
    selector: "myComponent",
    template: "<testWidget></testWidget>",
    directives: [testWidget]
})

Angular에서 오류가 발생합니다.

예외 : testWidget : (?)의 모든 매개 변수를 확인할 수 없습니다.

그래서 모델이 아직 정의되지 않았다고 생각했는데 ... 맨 위로 이동하겠습니다!

지금을 제외하고는 예외가 발생합니다.

원래 예외 : 모델 제공 업체 없음!

이 작업을 어떻게 수행합니까 ??

편집 : 모든 답변에 감사드립니다. 그것은 나를 올바른 길로 인도했습니다.

이것을 생성자에 삽입하려면 컴포넌트의 제공자에 추가해야합니다.

이것은 작동하는 것 같습니다.

import { Component, Input } from "@angular/core";

class Model {
    param1: string;
}

@Component({
    selector: "testWidget",
    template: "<div>This is a test and {{model.param1}} is my param.</div>",
    providers: [Model]
})

export class testWidget {
    constructor(private model: Model) {}
}

답변:


152

나는 이것을 시도 할 것이다 :

모델을 다음과 같은 별도의 파일로 분할합니다 model.ts.

export class Model {
    param1: string;
}

구성 요소로 가져옵니다. 이렇게하면 다른 구성 요소에서 사용할 수 있다는 추가 이점을 얻을 수 있습니다.

Import { Model } from './model';

구성 요소에서 초기화합니다.

export class testWidget {
   public model: Model;
   constructor(){
       this.model = new Model();
       this.model.param1 = "your string value here";
   }
}

html에서 적절하게 액세스하십시오.

@Component({
      selector: "testWidget",
      template: "<div>This is a test and {{model.param1}} is my param.</div>"
})

최신 도구 및 기술에 적응하는 것이 중요하기 때문에 @PatMigliaccio 의 의견을 답변에 추가하고 싶습니다 .

사용하는 경우 angular-cli전화를 걸면 ng g class model생성됩니다. 모델이 원하는 이름으로 대체됩니다.


1
흥미롭게도 ... 생성자 (개인 모델 : 모델)의 속기 (shorthand)를 시도하면 No Provider라는 오류가 발생합니다. 그러나 private model : Model = new Model ()로 정의하면 작동합니다. 왜 이런거야?
Scottie

7
저는 Angular 2 건축가는 아니지만 Angular에 대한 경험을 바탕으로 생성자를 통해 무언가를 가져올 때 주입 된 것으로 암시합니다. 삽입하려면 다음과 같은 공급자로 @Component에 추가해야합니다 providers: [Model].. 또한 Angular 2 Tour of Hero의 데모에 따라 해당 기능은 일반적으로 서비스와 같은 더 복잡한 클래스에 예약되어 있으므로 주입 가능 대신 속성으로 사용해야합니다.
Brendon Colburn

1
모델을 인스턴스화하는 방법에 문제가 있습니다 (사용하지 않음 new). 모델의 작성자가 호출되지 않는 것입니다. 그리고 그것은 instanceOf Model잘못된 것입니다
Poul를 Kruijt

하지만 시작할 생성자가 없었습니까? 나는 이것이이 구현에 대한 많은 문제라고 생각하지 않는다. 상황이 더 복잡해지면 확실합니다. 그래도 여전히 배우고 있습니다. 나는 방금 전에 사용하지 않는이 속기 방법을 배웠고 이와 new같은 간단한 경우에 좋아했습니다.
Brendon Colburn

5
사용하는 경우 angular-cli전화를 걸면 ng g class model생성됩니다. model원하는 이름으로 대체됩니다.
Pat Migliaccio

16

당신은 추가하지 않은 것을 문제 거짓말 Model로 중 하나 bootstrap(이 싱글 만들 것이다) 또는에 providers구성 요소 정의의 배열 :

@Component({
    selector: "testWidget",
    template: "<div>This is a test and {{param1}} is my param.</div>",
    providers : [
       Model
    ]
})

export class testWidget {
    constructor(private model: Model) {}
}

그리고 예, Model위에 정의해야 합니다 Component. 그러나 자신의 파일에 저장하는 것이 좋습니다.

그러나 여러 인스턴스를 생성 할 수있는 클래스가되기를 원한다면 new.

@Component({
    selector: "testWidget",
    template: "<div>This is a test and {{param1}} is my param.</div>"
})

export class testWidget {

    private model: Model = new Model();

    constructor() {}
}

1
모델은 클래스 일 뿐이며 가져 오기는 이상적으로 작동해야합니다. 왜 우리는 그것을 providers배열로 필요 합니까?
Pankaj Parkar

예,하지만 그의 템플릿은 여기서 작동하지 않습니다. model.param1이됩니다. 또한 그는 초기 값을 제공하지 않았습니까?
Brendon Colburn

@PankajParkar 난 여전히를 얻을 수 있기 때문에 No Provider for Model내가 제공 배열에 추가하지 않은 경우
Poul를 Kruijt

@PierreDuc 수업 export전에 가지고 Model있습니까?
Pankaj Parkar


6

귀하의 경우에는 동일한 페이지에 모델이 있지만 Component 클래스 뒤에 선언 했으므로을 forwardRef참조하는 데 사용해야 합니다 Class. 이 작업을 선호하지 않고 항상 model별도의 파일에 개체를 두십시오.

export class testWidget {
    constructor(@Inject(forwardRef(() => Model)) private service: Model) {}
}

또한 올바른 객체를 참조하기 위해 보간법을 변경해야합니다.

{{model?.param1}}

더 좋은 방법은 Model클래스를 다른 파일에 정의한 다음 필요할 때이를 수행하여 가져올 수 있다는 것입니다. 또한 export클래스 이름을 가져 와서 가져올 수 있습니다.

import { Model } from './model';

@BrendonColburn 감사합니다, 나는 당신의 대답에서 그것을 봤습니다. 그래서 나는 편집에 의미 내 대답 aftewards, 머리 주셔서 감사합니다 남자 :) 환호, 최대하지만이없는 생각
판 카즈 Parkar에게

5

내 코드는

    import { Component } from '@angular/core';

class model {
  username : string;
  password : string;
}

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})



export class AppComponent {

 username : string;
 password : string;
  usermodel = new model();

  login(){
  if(this.usermodel.username == "admin"){
    alert("hi");
  }else{
    alert("bye");
    this.usermodel.username = "";
  }    
  }
}

html은 다음과 같습니다.

<div class="login">
  Usernmae : <input type="text" [(ngModel)]="usermodel.username"/>
  Password : <input type="text" [(ngModel)]="usermodel.password"/>
  <input type="button" value="Click Me" (click)="login()" />
</div>

3
export class Car {
  id: number;
  make: string;
  model: string;
  color: string;
  year: Date;

  constructor(car) {
      {
        this.id = car.id;
        this.make = car.make || '';
        this.model = car.model || '';
        this.color = car.color || '';
        this.year = new Date(car.year).getYear();
      }
  }
}

|| 존재하지 않는 기본 데이터에 대한 매우 복잡한 데이터 개체에 매우 유용 할 수 있습니다.

. .

component.ts 또는 service.ts 파일에서 응답 데이터를 모델로 역 직렬화 할 수 있습니다.

// Import the car model
import { Car } from './car.model.ts';

// If single object
car = new Car(someObject);

// If array of cars
cars = someDataToDeserialize.map(c => new Car(c));

2

@brendon의 답변에서 제안하는 주석으로 angular-cli를 사용할 수 있습니다.

다음을 시도해 볼 수도 있습니다.

ng g class modelsDirectoy/modelName --type=model

/* will create
 src/app/modelsDirectoy
 ├── modelName.model.ts
 ├── ...
 ...
*/

마음에 곰 : ng g class ! == ng g c
그러나, 당신이 사용할 수있는 ng g cl귀하의 각도-CLI 버전에 따라 바로 가기로.


0

이것이 다소 오래된 질문이라는 것을 알고 있지만 테스트 위젯 클래스에 모델 변수를 잘못 추가했음을 지적하고 싶었습니다. Model 변수가 필요한 경우 구성 요소 생성자를 통해 전달하지 않아야합니다. 귀하는 그러한 방식으로 서비스 또는 기타 유형의 주사제를 전달하기위한 것입니다. 다른 구성 요소 내부에서 테스트 위젯을 인스턴스화하고 모델 객체를 전달해야하는 경우 각도 코어 OnInit 및 입력 / 출력 디자인 패턴을 사용하는 것이 좋습니다.

예를 들어, 코드는 실제로 다음과 같아야합니다.

import { Component, Input, OnInit } from "@angular/core";
import { YourModelLoadingService } from "../yourModuleRootFolderPath/index"

class Model {
    param1: string;
}

@Component({
    selector: "testWidget",
    template: "<div>This is a test and {{model.param1}} is my param.</div>",
    providers: [ YourModelLoadingService ]
})

export class testWidget implements OnInit {
    @Input() model: Model; //Use this if you want the parent component instantiating this
        //one to be able to directly set the model's value
    private _model: Model; //Use this if you only want the model to be private within
        //the component along with a service to load the model's value
    constructor(
        private _yourModelLoadingService: YourModelLoadingService //This service should
        //usually be provided at the module level, not the component level
    ) {}

    ngOnInit() {
        this.load();
    }

    private load() {
        //add some code to make your component read only,
        //possibly add a busy spinner on top of your view
        //This is to avoid bugs as well as communicate to the user what's
        //actually going on

        //If using the Input model so the parent scope can set the contents of model,
        //add code an event call back for when model gets set via the parent
        //On event: now that loading is done, disable read only mode and your spinner
        //if you added one

        //If using the service to set the contents of model, add code that calls your
        //service's functions that return the value of model
        //After setting the value of model, disable read only mode and your spinner
        //if you added one. Depending on if you leverage Observables, or other methods
        //this may also be done in a callback
    }
}

본질적으로 구조체 / 모델 인 클래스는 주입되어서는 안됩니다. 이는 제공된 범위 내에서 해당 클래스의 단일 공유 인스턴스 만 가질 수 있음을 의미하기 때문입니다. 이 경우 testWidget이 인스턴스화 될 때마다 종속성 주입기에 의해 Model의 단일 인스턴스가 생성됩니다. 모듈 수준에서 제공된 경우 해당 모듈 내의 모든 구성 요소 및 서비스간에 단일 인스턴스 만 공유됩니다.

대신 표준 객체 지향 관행을 따르고 클래스의 일부로 전용 모델 변수를 생성해야하며, 인스턴스를 인스턴스화 할 때 해당 모델에 정보를 전달해야하는 경우에서 제공하는 서비스 (주입 가능)에서 처리해야합니다. 부모 모듈. 이것은 의존성 주입과 통신이 각도에서 수행되는 방식입니다.

또한 다른 일부가 언급했듯이 별도의 파일에 모델 클래스를 선언하고 클래스를 가져와야합니다.

각도 문서 참조로 돌아가서 다양한 주석 및 클래스 유형에 대한 기본 페이지를 검토하는 것이 좋습니다. https://angular.io/guide/architecture

아키텍처 수준에서 Angular를 사용하는 방법을 이해하는 데 필수적이므로 모듈, 구성 요소 및 서비스 / 종속성 주입 섹션에 특히주의해야합니다. Angular는 매우 높은 수준이기 때문에 매우 아키텍처가 무거운 언어입니다. 우려 사항 분리, 종속성 주입 팩토리 및 브라우저 비교 가능성을위한 자바 스크립트 버전 관리는 주로 사용자를 위해 처리되지만 애플리케이션 아키텍처를 올바르게 사용해야합니다. 그렇지 않으면 예상대로 작동하지 않습니다.


0

아래와 같이 구성 요소 디렉토리에 model.ts를 만듭니다.

export module DataModel {
       export interface DataObjectName {
         propertyName: type;
        }
       export interface DataObjectAnother {
         propertyName: type;
        }
    }

그런 다음 위의 구성 요소 가져 오기에서 './model'에서 {DataModel}을 가져옵니다.

export class YourComponent {
   public DataObject: DataModel.DataObjectName;
}

DataObject에는 DataObjectName의 모든 속성이 있어야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.