Como é que eu declaro uma classe de modelo no meu componente Angular 2 usando um script?

Sou novo no Angular 2 e datilografo e estou a tentar seguir as melhores práticas.

em vez de usar um simples modelo de JavaScript ({ }), estou a tentar criar uma classe de TypeScript.

No entanto, o Angular 2 não parece gostar.

o meu código é:

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

e estou a usá-lo como:

import { testWidget} from "lib/testWidget";

@Component({
    selector: "myComponent",
    template: "<testWidget></testWidget>",
    directives: [testWidget]
})
Estou a receber um erro do Angular.

excepção: não é possível resolver todos os parâmetros para testWidget: (?).

Então eu pensei, modelo não é definido ainda... Vou levá-lo para o topo!

excepto que agora tenho a excepção:

excepção ORIGINAL: nenhum fornecedor para o modelo!

Como faço isso??

editar: obrigado a todos pela resposta. Levou-me ao caminho certo.

Para injectar isto no construtor, tenho de o Adicionar aos fornecedores do componente.

Isto parece funcionar.
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) {}
}
Author: Scottie, 2016-07-15

6 answers

Eu tentaria isto:

Divide o teu modelo num ficheiro separado chamado model.ts:

export class Model {
    param1: string;
}

Importem-no para o vosso componente. Isso lhe dará o benefício adicional de ser capaz de usá-lo em outros componentes:

Import { Model } from './model';

Inicializar no componente:

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

Acesse-o apropriadamente no html:

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

Quero acrescentar à resposta um comentário feito por @PatMigliaccio porque é importante adaptar-se às mais recentes ferramentas e tecnologias:

Se estiver a usar {[5] } pode ligar para ng g class model e ele irá gerá-lo para si. modelo sendo substituído por qualquer nome que você desejar.

 89
Author: Brendon Colburn, 2018-02-07 18:52:46

O problema é que ainda não adicionaste Model nem ao bootstrap (que o fará um singleton), nem ao providers conjunto da definição do teu componente:

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

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

E sim, você deve definir {[[2]} acima do Component. Mas melhor seria colocá-lo no seu próprio arquivo.

Mas se você quiser que seja apenas uma classe A partir da qual você pode criar várias instâncias, é melhor usar 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() {}
}
 11
Author: PierreDuc, 2016-07-15 15:01:24

No seu caso, está a ter o modelo na mesma página, mas tem-no declarado depois da sua classe de componentes, por isso, tem de usar forwardRef para se referir a Class. não prefira fazer isto, tenha sempre model objecto em ficheiro separado.

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

Além disso, terá de alterar a sua interpolação para se referir ao objecto correcto

{{model?.param1}}

O melhor que você deve fazer é, você pode ter sua classe Model definir em arquivos diferentes e, em seguida, importá - lo como um quando você precisa ao fazê-lo. Também tenha export antes de você Nome da classe, para que você possa importá-lo.

import { Model } from './model';
 5
Author: Pankaj Parkar, 2016-07-15 15:02:47

O meu código é

    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 = "";
  }    
  }
}

E o html é assim:

<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
Author: Ahmed Basha, 2017-01-24 02:54:47

Você pode usar o angular-cli como os comentários na resposta de @brendon sugerem.

Você também pode querer tentar:

ng g class modelsDirectoy/modelName --type=model

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

Tenha em mente: ng g class !== ng g c
No entanto, pode usar ng g cl como atalho, dependendo da sua versão angular-cli.

 0
Author: xyz, 2018-04-19 17:22:44

Eu percebo que esta é uma pergunta um pouco mais antiga, mas eu só queria salientar que você adicionou a variável modelo para a sua classe de widget teste incorretamente. Se você precisa de uma variável modelo, você não deve estar tentando passar através do construtor de componentes. Você só tem a intenção de passar serviços ou outros tipos de injetáveis dessa forma. Se estiver a instanciar o seu elemento de teste dentro de outro componente e precisar de passar por um objecto modelo como, eu recomendaria a utilização do núcleo angular OnInit and Input/Output design patterns.

Como exemplo, o seu código deve ser parecido com isto:

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

Uma classe que é essencialmente apenas uma estrutura/modelo não deve ser injectada, porque significa que só se pode ter um único instanciamento partilhado dessa classe no âmbito que foi fornecido. Neste caso, isso significa que uma única instância de modelo é criada pelo injector de dependência cada vez que testWidget é instanciado. Se fosse fornecido ao nível do módulo, você só ter uma única instância compartilhada entre todos os componentes e serviços dentro desse módulo.

Em vez disso, deverá estar a seguir práticas orientadas a objectos e a criar uma variável de modelo privado como parte da classe, e se necessitar de passar informação para esse modelo quando instanciar a instância, essa deverá ser tratada por um serviço (injectável) fornecido pelo módulo pai. Esta é a forma como a injecção de dependência e a comunicação se destinam a ser realizados em angular.

{[[2]}também, como alguns dos outros mencionados, você deve estar declarando suas classes modelo em um arquivo separado e importar a classe.

Eu recomendaria fortemente voltar para a referência da documentação angular e rever as páginas básicas sobre as várias anotações e tipos de classe: https://angular.io/guide/architecture

Deve prestar especial atenção às secções sobre módulos, Componentes e serviços / injeção de Dependência, uma vez que estas são essencial para entender como usar Angular em um nível arquitetônico. Angular é uma linguagem muito arquitetônica pesada porque é de alto nível. Separação de preocupações, fábricas de injeção de dependências e versionamento javascript para a comparabilidade do navegador são tratados principalmente para você, mas você tem que usar a arquitetura de aplicativos corretamente ou você vai encontrar coisas que não funcionam como você espera.

 0
Author: user2904660, 2018-04-23 16:46:51