angular - कोणीय डि त्रुटि-अपवाद: सभी मापदंडों को हल नहीं कर सकते




angular2-di (20)

आपको @Component डेकोरेटर या उस मॉड्यूल में प्रदाता सरणी को जोड़ना होगा जहां आपका घटक घोषित किया गया है। घटक के अंदर आप नीचे के रूप में कर सकते हैं:

@Component({
  moduleId: module.id,
  selector: 'pm-header',
  templateUrl: 'header.component.html',
  styleUrls: ['header.component.css'],
  directives: [ROUTER_DIRECTIVES, NgClass],
  providers: [MobileService]
})

मैंने कोणीय में एक बुनियादी ऐप बनाया है, लेकिन मुझे एक अजीब समस्या का सामना करना पड़ा है, जहां मैं अपने किसी घटक में एक सेवा को इंजेक्ट नहीं कर सकता। हालांकि यह मेरे द्वारा बनाए गए तीन अन्य घटकों में से किसी में भी ठीक है।

शुरुआत के लिए, यह सेवा है:

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

@Injectable()
export class MobileService {
  screenWidth: number;
  screenHeight: number;

  constructor() {
    this.screenWidth = window.outerWidth;
    this.screenHeight = window.outerHeight;

    window.addEventListener("resize", this.onWindowResize.bind(this) )
  }

  onWindowResize(ev: Event) {
    var win = (ev.currentTarget as Window);
    this.screenWidth = win.outerWidth;
    this.screenHeight = win.outerHeight;
  }

}

और इसके साथ काम करने से मना करने वाला घटक:

import { Component, } from '@angular/core';
import { NgClass } from '@angular/common';
import { ROUTER_DIRECTIVES } from '@angular/router';

import {MobileService} from '../';

@Component({
  moduleId: module.id,
  selector: 'pm-header',
  templateUrl: 'header.component.html',
  styleUrls: ['header.component.css'],
  directives: [ROUTER_DIRECTIVES, NgClass],
})
export class HeaderComponent {
  mobileNav: boolean = false;

  constructor(public ms: MobileService) {
    console.log(ms);
  }

}

ब्राउज़र कंसोल में मुझे जो त्रुटि मिलती है वह यह है:

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

मेरे पास बूटस्ट्रैप फ़ंक्शन में सेवा है इसलिए इसके पास एक प्रदाता है। और मुझे यह समस्या के बिना मेरे किसी भी अन्य घटक के निर्माता में इंजेक्ट करने में सक्षम लगता है।


आपको यह त्रुटि मिलती है यदि आपके पास सेवा ए है जो स्थिर संपत्ति / सेवा बी की विधि पर निर्भर करती है और सेवा बी स्वयं सेवा ट्राउट निर्भरता इंजेक्शन पर निर्भर करती है। तो यह एक तरह की परिपत्र निर्भरता है, हालांकि यह तब से नहीं है जब संपत्ति / विधि स्थिर है। संभवतः एक बग जो एओटी के साथ संयोजन में होता है।


इसे उस फ़ाइल से आयात करें जहां इसे बैरल के बजाय सीधे घोषित किया गया है।

मुझे नहीं पता कि वास्तव में इस मुद्दे का क्या कारण है, लेकिन मैंने इसे कई बार (शायद किसी प्रकार की परिपत्र निर्भरता) उल्लेख किया है।

बैरल में निर्यात के क्रम को बदलकर इसे भी ठीक किया जाना चाहिए (विवरण नहीं पता, लेकिन साथ ही उल्लेख किया गया था)


एक और संभावना emitDecoratorMetadata में सच करने के लिए सेट emitDecoratorMetadata नहीं है

{
  "compilerOptions": {

     ...

    "emitDecoratorMetadata": true,

     ...

    }

}

कोणीय 2.2.3 रूप में अब एक forwardRef() उपयोगिता फ़ंक्शन है जो आपको उन प्रदाताओं को इंजेक्ट करने की अनुमति देता है जिन्हें अभी तक परिभाषित नहीं किया गया है।

परिभाषित नहीं होने से मेरा मतलब है कि निर्भरता इंजेक्शन मानचित्र पहचानकर्ता को नहीं जानता है। परिपत्र निर्भरता के दौरान यही होता है। आप कोणीय में परिपत्र निर्भरताएं हो सकती हैं जो कि अनसंग करना और देखना बहुत कठिन हैं।

export class HeaderComponent {
  mobileNav: boolean = false;

  constructor(@Inject(forwardRef(() => MobileService)) public ms: MobileService) {
    console.log(ms);
  }

}

मूल प्रश्न के स्रोत कोड में कंस्ट्रक्टर के पैरामीटर पर @Inject(forwardRef(() => MobileService)) को @Inject(forwardRef(() => MobileService)) से समस्या ठीक हो जाएगी।

संदर्भ

कोणीय 2 मैनुअल: फारवर्डरफ

कोणीय 2 में आगे के संदर्भ


खैर मेरे लिए यह मुद्दा और भी अधिक कष्टप्रद था, मैं एक सेवा के भीतर एक सेवा का उपयोग कर रहा था और इसे appModule में निर्भरता के रूप में जोड़ना भूल गया था! आशा है कि यह किसी को ऐप को तोड़ने के लिए कई बार बचाने में मदद करता है ताकि इसे फिर से बनाया जा सके


जैसा कि पहले ही कहा गया है, यह मुद्दा बैरल के भीतर निर्यात आदेश के कारण होता है जो परिपत्र निर्भरता के कारण होता है।

अधिक विस्तृत विवरण यहां है: https://.com/a/37907696/893630


दिए गए पिछले उत्तरों के अलावा, ऐसा लगता है कि यह त्रुटि तब डाली गई है जब आपकी इंजेक्टेबल सेवा वास्तविक @Injectable() डेकोरेटर को याद कर रही है। इससे पहले कि आप चक्रीय निर्भरता बात और आपके आयात / निर्यात के क्रम को डिबग करें, एक साधारण जांच करें कि क्या आपकी सेवा वास्तव में @Injectable() परिभाषित है।

यह वर्तमान कोणीय नवीनतम, कोणीय 2.1.0 पर लागू होता है।

मैंने इस मामले पर एक मुद्दा खोला


मुझे इस त्रुटि का सामना करना पड़ा है सेवा का नाम, यानी कंस्ट्रक्टर (निजी myService: MyService )।

गलत वर्तनी वाली सेवाओं के लिए, मैं क्रोम-> कंसोल में पेज का निरीक्षण करके यह निर्धारित करने में सक्षम था कि कौन सी सेवा समस्या थी (मैंने कंस्ट्रक्टर में कई सूचीबद्ध की थी)। आप ऑब्जेक्ट ऑब्जेक्ट, ऑब्जेक्ट ऑब्जेक्ट को प्रदर्शित करके संदेश के "पैरामीटर" सरणी सूची के भाग के रूप में देखेंगे? (या कुछ इस तरह का)। नोटिस कहाँ "?" वह है और यह उस सेवा की स्थिति है जो समस्या पैदा कर रही है।


मुझे सेवा ए में सेवा बी और इसके विपरीत इंजेक्शन लगाने से भी इसका सामना करना पड़ा।

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

इसलिए, मेरी निम्नलिखित सिफारिशें हैं:

  • यदि आपको लगता है कि कक्षाएं बहुत बार बातचीत कर रही हैं (मैं फीचर ईर्ष्या के बारे में बात कर रहा हूं), तो आप 2 सेवाओं को 1 कक्षा में विलय करने पर विचार कर सकते हैं।
  • यदि उपरोक्त आपके लिए काम नहीं करता है, तो संदेशों का आदान-प्रदान करने के लिए एक 3 सेवा , (एक EventService ) का उपयोग करने पर विचार करें, जो दोनों सेवाएं इंजेक्ट कर सकती हैं।

मेरे मामले में मैं " NativeDateAdapter " को " format(date: Date, displayFormat: Object) " format(date: Date, displayFormat: Object) विधि को ओवरराइड करने के लिए विस्तारित करने का प्रयास कर रहा था।

AngularMaterial-2 DatePicker में।

इसलिए मूल रूप से मैं @Injectable एनोटेशन जोड़ना भूल गया।

अपने "CustomDateAdapter" वर्ग में इसे जोड़ने के बाद:

@Injectable({
  providedIn: 'root'
})

त्रुटि हो गई है।


मेरे मामले में यह एक परिपत्र संदर्भ था। मेरे पास MyService कॉलिंग MyService2 और MyService2 कॉलिंग MyService थी।

अच्छा नही :(


मेरे मामले में, ऐसा इसलिए हुआ क्योंकि मैंने एक कंस्ट्रक्टर पैरामीटर के लिए प्रकार घोषित नहीं किया था।

मेरे पास कुछ ऐसा था:

constructor(private URL, private http: Http) { }

और फिर इसे नीचे दिए गए कोड में बदलकर मेरी समस्या हल कर दी।

constructor(private URL : string, private http: Http) {}

मेरे मामले में, कारण निम्नलिखित था:

  • मेरी इंजेक्टेबल सेवा ए ने एक अन्य वर्ग बी बढ़ाया
  • B के पास एक कंस्ट्रक्टर था जिसे एक तर्क की आवश्यकता थी
  • मैंने ए में किसी भी निर्माता को परिभाषित नहीं किया था

परिणामस्वरूप, जब कोई ऑब्जेक्ट A बनाने का प्रयास किया जाता है, तो डिफ़ॉल्ट निर्माता विफल हो जाता है। मुझे नहीं पता कि यह एक संकलन त्रुटि क्यों नहीं थी।

मैंने इसे ए में केवल एक कंस्ट्रक्टर जोड़कर तय किया, जिसे बी का कंस्ट्रक्टर सही कहा जाता है।


मेरे मामले में, मैं उसी घटक फ़ाइल से एक वर्ग और एक Enum निर्यात कर रहा था:

mComponent.component.ts :

export class MyComponentClass{...}
export enum MyEnum{...}

फिर, मैं MyEnum एक बच्चे से MyEnum का उपयोग करने की कोशिश कर रहा था। यह सभी पैरामीटर त्रुटि को हल नहीं कर सकता था।

MyEnum को MyComponentClass से अलग फ़ोल्डर में ले MyComponentClass , इससे मेरी समस्या हल हो गई!

जैसा कि गुंटर ज़ोचबॉयर ने उल्लेख किया है, यह एक सेवा या घटक के कारण परिपत्र रूप से निर्भर होने के कारण हो रहा है।


मेरे लिए यह इसलिए था क्योंकि मैंने संकलन समय को और तेज़ बनाने की कोशिश करते हुए -aot फ्लैग का उपयोग करना बंद कर दिया था।

 ng serve -aot

मेरे लिए, मुझे यह त्रुटि तब मिली जब मैंने गलती से इस आयात को पॉलीफ़िल्स की फ़ाइल में अक्षम कर दिया था, आपको यह सुनिश्चित करने की आवश्यकता है कि उस त्रुटि से बचने के लिए इसे आयात किया जाए।

/** Evergreen browsers require these. **/
// Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove.
import 'core-js/es7/reflect';

यदि आपकी सेवा एक घटक के रूप में उसी फ़ाइल में परिभाषित की गई है (जो इसका उपभोग करती है) और सेवा को फ़ाइल में घटक के बाद परिभाषित किया गया है तो आपको यह त्रुटि मिल सकती है। यह उसी 'फॉरवर्ड रीफ' मुद्दे के कारण है जिसका दूसरों ने उल्लेख किया है। इस समय VSCode आपको यह त्रुटि दिखाने के बारे में महान नहीं है और बिल्ड सफलतापूर्वक संकलित करता है।

कंपाइलर के काम करने के तरीके (शायद पेड़ हिलने से संबंधित) के कारण बिल्ड - --aot साथ रनिंग इस समस्या को मास्क कर सकती है।

समाधान: सुनिश्चित करें कि सेवा किसी अन्य फ़ाइल में या घटक परिभाषा से पहले परिभाषित की गई है। (मुझे यकीन नहीं है कि अगर फॉरवर्ड का इस्तेमाल इस मामले में किया जा सकता है, लेकिन ऐसा करना अनाड़ी लगता है)।

यदि मेरे पास एक बहुत ही सरल सेवा है जो बहुत दृढ़ता से एक घटक (एक दृश्य मॉडल की तरह) से जुड़ी है - जैसे। ImageCarouselComponent , मैं इसे ImageCarouselComponent.service.ts नाम दे सकता हूं ताकि यह मेरी अन्य सेवाओं के साथ मिश्रित न हो।


लापता @Injectable() डेकोरेटर के अलावा

अमूर्त वर्ग में @Injectable() डेकोरेटर का उत्पादन सेवा के लिए सभी मापदंडों को हल नहीं कर सकता: ((?) सजावटकर्ता को MyService साथ-साथ व्युत्पन्न वर्ग BaseService में मौजूद होना चाहिए

//abstract class
@Injectable()
abstract class BaseService { ... }

//MyService    
@Injectable()
export class MyService extends BaseService {
.....
}

हालांकि बैरल के भीतर से निर्यात की गई कक्षाओं के आदेश का उल्लेख किया गया है, निम्नलिखित परिदृश्य भी एक ही प्रभाव पैदा कर सकता है।

मान लीजिए कि आपके पास A , B और C एक ही फ़ाइल के भीतर से निर्यात की गई कक्षाएं हैं, जहां A B और C पर निर्भर करता C :

@Injectable()
export class A {
    /** dependencies injected */
    constructor(private b: B, private c: C) {}
}

@Injectable()
export class B {...}

@Injectable()
export class C {...}

चूंकि आश्रित वर्ग (यानी इस मामले में B और C ) को अभी तक कोणीय के लिए नहीं जाना जाता है, ( शायद कक्षा A पर एंगुलर की निर्भरता इंजेक्शन प्रक्रिया के दौरान रन-टाइम में ) त्रुटि उठाई जाती है।

उपाय

समाधान यह है कि जिस कक्षा में डीआई किया जाता है, उससे पहले आश्रित कक्षाओं को घोषित और निर्यात करें।

उक्त मामले में वर्ग A को सही घोषित किया जाता है क्योंकि उसकी निर्भरताएँ परिभाषित की जाती हैं:

@Injectable()
export class B {...}

@Injectable()
export class C {...}

@Injectable()
export class A {
    /** dependencies injected */
    constructor(private b: B, private c: C) {}
}




angular2-di