टाइपस्क्रिप्ट का उपयोग करके मैं अपने कोणीय 2 घटक में एक मॉडल वर्ग कैसे घोषित कर सकता हूं?


82

मैं कोणीय 2 और टाइपस्क्रिप्ट के लिए नया हूं और सर्वोत्तम प्रथाओं का पालन करने की कोशिश कर रहा हूं।

एक साधारण जावास्क्रिप्ट मॉडल ({}) का उपयोग करने के बजाय, मैं टाइपस्क्रिप्ट क्लास बनाने का प्रयास कर रहा हूं।

हालाँकि, कोणीय 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]
})

मुझे कोणीय से एक त्रुटि मिल रही है:

अपवाद: परीक्षण के लिए सभी मापदंडों को हल नहीं कर सकते हैं: (?)।

तो मैंने सोचा, मॉडल अभी तक परिभाषित नहीं है ... मैं इसे शीर्ष पर ले जाऊंगा!

अब मुझे छोड़कर अपवाद मिलता है:

मूल अपवाद: मॉडल के लिए कोई प्रदाता नहीं!

मैं इसे कैसे पूर्ण करूं??

संपादित करें: उत्तर के लिए सभी को धन्यवाद। इसने मुझे सही रास्ते पर ले गया।

कंस्ट्रक्टर में इसे इंजेक्ट करने के लिए, मुझे इसे घटक पर प्रदाताओं को जोड़ना होगा।

यह काम करने के लिए प्रकट होता है:

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

जवाबों:


153

मैं यह कोशिश करूँगा:

एक अलग फ़ाइल में अपने मॉडल को विभाजित करें 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
दिलचस्प ... यदि मैं निर्माणकर्ता (निजी मॉडल: मॉडल) की शॉर्टहैंड की कोशिश करता हूं, तो मुझे त्रुटि मिलती है कि मैं कोई प्रदाता नहीं हूं। हालांकि, अगर मैं इसे निजी मॉडल के रूप में परिभाषित करता हूं: मॉडल = नया मॉडल (), यह काम करता है। ऐसा क्यों है?
स्कूटी

7
मैं एक कोणीय 2 वास्तुकार नहीं हूं, लेकिन जब आप निर्माणकर्ता के माध्यम से कुछ लाते हैं, तो आप इसे इंजेक्ट कर रहे हैं के माध्यम से कोणीय के साथ मेरे अनुभव के आधार पर। इंजेक्शन लगाने के लिए आवश्यक है कि आप इसे इस तरह प्रदाता के रूप में @Component में जोड़ें providers: [Model]:। साथ ही हीरो के डेमो के कोणीय 2 टूर के अनुसार आपको बस एक इंजेक्शन के बजाय एक संपत्ति के रूप में जाना चाहिए क्योंकि यह कार्यक्षमता आमतौर पर सेवाओं जैसे अधिक जटिल वर्गों के लिए आरक्षित होती है।
ब्रेंडन कॉलबर्न

1
मॉडल को तत्काल करने के अपने तरीके के साथ समस्या (उपयोग नहीं new)। यह है कि मॉडल के अवरोधक को बुलाया नहीं जाएगा। और वह instanceOf Modelझूठा होगा
पौल क्रुजित

लेकिन शुरू करने के लिए कोई कंस्ट्रक्टर नहीं था? मैं इसे इस कार्यान्वयन के लिए एक समस्या के रूप में नहीं देखता। यदि चीजें अधिक जटिल हो जाती हैं तो सुनिश्चित करें। मैं अभी भी बहुत कुछ सीख रहा हूँ। मैंने सिर्फ newदूसरे दिन का उपयोग न करने और इस तरह के सरल मामलों के लिए इसे अपनाने का यह शॉर्टहैंड तरीका सीखा ।
ब्रेंडन कॉलबर्न

5
यदि आप उपयोग कर रहे हैं तो आप angular-cliकॉल कर सकते हैं ng g class modelऔर यह आपके लिए उत्पन्न करेगा। modelजो भी नामकरण आपकी इच्छा से प्रतिस्थापित किया जा रहा है।
पैट मिगलियाकियो

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सरणी में इसकी आवश्यकता क्यों है ?
पंकज पारकर

हाँ, लेकिन उनकी टेम्प्लेटिंग यहाँ काम नहीं करेगी, यह model.param1 होगा। इसके अलावा, उन्होंने इसे शुरुआती मूल्य नहीं दिया है?
ब्रेंडन कॉलबर्न जुएल

@PankajParkar क्योंकि मैं अभी भी एक No Provider for Modelअगर मैं इसे प्रदाताओं सरणी में जोड़ नहीं है
Poul Kruijt

@PierreDuc आपके पास कक्षा exportसे पहले है Model?
पंकज पारकर


6

आपके मामले में आप एक ही पृष्ठ पर मॉडल कर रहे हैं, लेकिन आपने इसे अपने घटक वर्ग के बाद घोषित किया है, इसलिए आपको इसका उपयोग forwardRefकरने की आवश्यकता है Classऐसा करना पसंद न करें, हमेशा modelअलग फ़ाइल में ऑब्जेक्ट रखें।

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

इसके अतिरिक्त आपको सही वस्तु को संदर्भित करने के लिए आपको प्रक्षेप दृश्य को बदलना होगा

{{model?.param1}}

आपको जो बेहतर काम करना चाहिए वह यह है कि आप अपनी Modelक्लास को अलग-अलग फ़ाइल में परिभाषित कर सकते हैं और फिर इसे तब आयात कर सकते हैं जब आपको इसकी आवश्यकता होती है। इसके अलावा है exportइससे पहले कि आप वर्ग के नाम, ताकि आप इसे आयात कर सकते हैं।

import { Model } from './model';

@BrendonColburn धन्यवाद आदमी, मैंने देखा कि आपके उत्तर में। तो मैंने सोचा कि मेरे जवाब का संपादन करने का कोई मतलब नहीं है, धन्यवाद आदमी के लिए हालांकि, चीयर्स :)
पंकज पारकर

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>

4
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();
      }
  }
}

|| डिफ़ॉल्ट डेटा के लिए बहुत जटिल डेटा ऑब्जेक्ट के लिए सुपर उपयोगी बन सकता है जो मौजूद नहीं है।

। ।

अपने कंपोनेंट में .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));

3

आप @ ब्रेंडन के उत्तर सुझाव में टिप्पणियों के रूप में कोणीय-क्लि का उपयोग कर सकते हैं।

आप भी कोशिश कर सकते हैं:

ng g class modelsDirectoy/modelName --type=model

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

ध्यान में रखें ng g class :! == ng g c
हालांकि, आप ng g clअपने कोणीय-क्ली संस्करण के आधार पर शॉर्टकट के रूप में उपयोग कर सकते हैं ।


0

मुझे लगता है कि यह कुछ हद तक पुराना सवाल है, लेकिन मैं सिर्फ यह बताना चाहता था कि आपने मॉडल वेरिएबल को अपने टेस्ट विजेट क्लास में गलत तरीके से जोड़ा है। यदि आपको एक मॉडल चर की आवश्यकता है, तो आपको इसे घटक निर्माता के माध्यम से पारित करने की कोशिश नहीं करनी चाहिए। आप केवल इस तरह से सेवाओं या अन्य प्रकार के इंजेक्शन को पारित करने के लिए अभिप्रेत हैं। यदि आप किसी अन्य घटक के अंदर अपने परीक्षण विजेट को इंस्टेंट कर रहे हैं और एक मॉडल ऑब्जेक्ट को पास करने की आवश्यकता है, तो मैं कोणीय कोर ऑनइनिट और इनपुट / आउटपुट डिज़ाइन पैटर्न का उपयोग करने की सलाह दूंगा।

एक उदाहरण के रूप में, आपके कोड को वास्तव में कुछ इस तरह दिखना चाहिए:

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

एक वर्ग जो अनिवार्य रूप से सिर्फ एक संरचना / मॉडल को इंजेक्ट नहीं किया जाना चाहिए, क्योंकि इसका मतलब है कि आप उस वर्ग के केवल एक ही साझा इंस्टेंसेस को उस दायरे में ले सकते हैं जो इसे प्रदान किया गया था। इस मामले में, इसका मतलब है कि मॉडल का एक एकल उदाहरण निर्भरता इंजेक्टर द्वारा हर बार बनाया जाता है जब टेस्टवेट को तत्काल किया जाता है। यदि यह मॉड्यूल स्तर पर प्रदान किया गया था, तो आपके पास उस मॉड्यूल के भीतर सभी घटकों और सेवाओं के बीच एक ही उदाहरण होगा।

इसके बजाय, आपको मानक ऑब्जेक्ट ओरिएंटेड प्रथाओं का पालन करना चाहिए और कक्षा के हिस्से के रूप में एक निजी मॉडल चर बनाना चाहिए, और यदि आपको उस मॉडल में जानकारी पास करने की आवश्यकता है, जब आप इंस्टेंस को इंस्टाल करते हैं, जिसे एक सेवा (इंजेक्शन) द्वारा नियंत्रित किया जाना चाहिए मूल मॉड्यूल। इस प्रकार दोनों निर्भरता इंजेक्शन और संचार कोणीय में प्रदर्शन करने का इरादा है।

इसके अलावा, कुछ अन्य के रूप में, आपको अपनी मॉडल कक्षाओं को एक अलग फ़ाइल में घोषित करना चाहिए और कक्षा को आयात करना चाहिए।

मैं दृढ़ता से कोणीय प्रलेखन संदर्भ और विभिन्न एनोटेशन और वर्ग प्रकारों पर मूल बातें पृष्ठों की समीक्षा करने की सिफारिश करूंगा: https://angular.io/guide/altecture

आपको मॉड्यूल, कंपोनेंट्स और सर्विसेज / डिपेंडेंसी इंजेक्शन पर सेक्शन पर विशेष ध्यान देना चाहिए क्योंकि ये समझने के लिए आवश्यक हैं कि वास्तु स्तर पर कोणीय का उपयोग कैसे करें। कोणीय एक बहुत ही वास्तुकला भारी भाषा है क्योंकि यह बहुत उच्च स्तर है। चिंताओं की जुदाई, निर्भरता इंजेक्शन कारखानों और ब्राउज़र तुलना के लिए जावास्क्रिप्ट संस्करण मुख्य रूप से आपके लिए संभाला जाता है, लेकिन आपको उनके एप्लिकेशन आर्किटेक्चर का सही ढंग से उपयोग करना होगा या आपको उम्मीद के मुताबिक काम नहीं मिलेंगे।


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 से सभी गुण होने चाहिए।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.