2014-12-10 11 views
6

मैं टाइपस्क्रिप्ट का उपयोग करने के लिए एक कोणीय ऐप को परिवर्तित कर रहा हूं, लेकिन यह एक सामान्य टाइपस्क्रिप्ट प्रश्न है, कोणीय के बारे में नहीं। कोणीय जे एस फ़ाइलें पंक्तियों के साथ कर रहे हैं:टाइपस्क्रिप्ट - उसे यह होना चाहिए? (जहां यह == वैश्विक दायरा)

(function() { 
    var app = angular.module('myModule', []); 
    app.controller('myController', ['$scope', 
    function ($scope) { 
     $scope.myNewProperty = "Bob"; 
    } 
    ]); 
})(); 

और मैं परिवर्तित कर दिया है कि सुंदर टाइपप्रति वर्ग वाक्यविन्यास के लिए:

class myController { 
    constructor($scope) { 
     $scope.myNewProperty = "Bob"; 
    } 
} 

angular.module('myModule', []).controller("myController", myController); 

सभी, ठीक काम करता है उत्पन्न जे एस को छोड़कर जे एस के अनुसार लिपटे नहीं है मॉड्यूल पैटर्न (यानी बाहरी अज्ञात फ़ंक्शन में):

var myController =  (function() { 
     app.controller('myController', ['$scope', 
     function ($scope) { 
      $scope.myNewProperty = "Bob"; 
     } 
     ]); 
    })(); 

var app = angular.module('myModule', []); 

तो मेरा नियंत्रक अब वैश्विक है। अगर मैं एक टाइपप्रति मॉड्यूल में वर्ग शब्दों में कहें, तो js एक वैश्विक चर के रूप में मॉड्यूल का नाम के साथ उत्पन्न करता है:

var TsModule; 
(function (TsModule) { 
    var myController =  (function() { 
      app.controller('myController', ['$scope', 
      function ($scope) { 
       $scope.myNewProperty = "Bob"; 
      } 
      ]); 
     })(); 

    var app = angular.module('myModule', []); 
})(TsModule || (TsModule = {})); 

मैं टाइपप्रति इस तरह से वैश्विक क्षेत्र प्रदूषण को कैसे रोकूं? मैं सिर्फ यह सब एक अच्छा स्थानीय दायरे में लपेटा चाहता हूँ। मैंने इसे कहीं और कहा है "बस पुराने जेएस सिंटैक्स पर वापस जाएं" (यानी कोई टाइपस्क्रिप्ट क्लास नहीं)। How can I define an AngularJS service using a TypeScript class that doesn't pollute the global scope?

लेकिन टाइपस्क्रिप्ट/है/कक्षा वाक्यविन्यास का उपयोग करके हम का पूरा बिंदु। टाइपस्क्रिप्ट किसी भी (समझदार) जेएस प्रोग्रामर के साथ बाधाओं पर है जो वैश्विक नहीं जाना जानता है?

+0

थोड़ी देर के बाद से मैंने टाइपस्क्रिप्ट का उपयोग किया था, इसलिए मैं इस पर बंद हो सकता हूं, लेकिन क्या आपने उपरोक्त टाइपस्क्रिप्ट कोड को तुरंत लागू किए गए लैम्ब्डा फ़ंक्शन में लपेटने की कोशिश की है? '((=)> { // कोड यहाँ ... })();' –

+0

मैं हताशा मिलता है, लेकिन अपने सभी फ़ाइलों के लिए एकमात्र, अच्छी तरह से परिभाषित मॉड्यूल नाम का उपयोग शायद ही वैश्विक क्षेत्र को प्रदूषित कर रहा है। यह वैश्विक दायरे पर एक एकल चर बना देगा, और फिर भी, यदि आप अपनी कक्षाओं का निर्यात नहीं कर रहे हैं, तो यह कभी खाली वस्तु से अधिक नहीं होगा। यह एक बहुत मामूली मुद्दा है। – Josh

+1

बस एफवाईआई (आप पहले से ही जानते हैं) कक्षा अभिव्यक्तियां अगले टीएस में आ रही हैं जो उन्हें आईआईएफई में अनुमति देगी। इसके अलावा ओपी के लिए टाइपस्क्रिप्ट में मॉड्यूल पैटर्न पर इस वीडियो (मैंने बनाया) आपके लिए उपयोगी हो सकता है: https://www.youtube.com/watch?v=KDrWLMUY0R0&hd=1 – basarat

उत्तर

4

आप बस मॉड्यूल में ही वैश्विक होगा एक module

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

तो यह टाइपप्रति:

module MyModule { 
    class MyClass { 
    constructor(){} 
    } 
} 

निम्नलिखित जे एस का उत्पादन होगा:

var MyModule; 
(function (MyModule) { 
    var MyClass = (function() { 
     function MyClass() { 
     } 
     return MyClass; 
    })(); 
})(MyModule || (MyModule = {})); 
+1

हाय, उत्तर देने के लिए धन्यवाद। मैं अपनी लाइन पर विस्तार करने के लिए अपने प्रश्न को संपादित करने की प्रक्रिया में था कि "यदि मैं कक्षा को टाइपस्क्रिप्ट मॉड्यूल में डालता हूं, तो जेएस मॉड्यूल नाम के साथ वैश्विक चर के रूप में उत्पन्न होता है:" - संपादन जेनरेट कोड था जो सुंदर है तुम्हारा जितना ही उतना ही है। मुद्दा यह है कि (आपके उदाहरण में) var MyModule अब वैश्विक है। हमने मॉड्यूल ग्लोबल के लिए एक नियंत्रक ग्लोबल को बदल दिया है। यदि कोई अन्य जावास्क्रिप्ट लाइब्रेरी में MyModule वैश्विक चर है तो अराजकता आती है! – user603563

+1

@ user603563 - वास्तव में नहीं क्योंकि यह खुलासा मॉड्यूल पैटर्न का उपयोग कर रहा है। इसलिए यह मॉड्यूल को फिर से परिभाषित नहीं करेगा यदि यह पहले से मौजूद है। कैओस केवल तभी आएगा जब आप उस मॉड्यूल में कुछ जोड़ते हैं जिसे आप बाहरी रूप से उपलब्ध होने की उम्मीद करते हैं। इस मामले में आप कक्षा में कक्षा को नहीं जोड़ रहे हैं, इसलिए कभी भी संघर्ष नहीं होगा। यह सिर्फ एक गुजर रहा है। – Josh

+1

मैं अभी अपने जेएस संदर्भों पर वापस गया और हां फिर से सीखा कि पहले घोषित माइओब्जेक्ट को निचोड़ने के बजाय, मायऑब्जेक्ट के बाद के var-ing को केवल मौजूदा ऑब्जेक्ट में जोड़ दिया जाएगा (या इस मामले में, कुछ भी नहीं बदला जाएगा MyObject के लिए किया जा रहा है) ठीक है, ठीक है (हालांकि मैं नाराज हूं क्योंकि यह जवाब नहीं देता है कि टाइपस्क्रिप्ट पूरी तरह से प्रदूषण वैश्विक दायरे से बच सकता है) मैं इसे उत्तर के रूप में चिह्नित करूंगा क्योंकि इन टिप्पणियों के साथ यह पर्याप्त रूप से समझाता है कि यह क्यों नहीं करता जैसा कि मैंने सोचा था ... – user603563

2

त्वरित अपडेट

टाइपप्रति के नवीनतम संस्करण में आप यह कर सकते हैं घोंसला एक Iife अंदर एक वर्ग:

(() => { 
    class Example { 

    } 
})(); 

जिसके परिणामस्वरूप उत्पादन होता है:

(function() { 
    var Example = (function() { 
     function Example() { 
     } 
     return Example; 
    }()); 
})(); 

मूल उत्तर

आप टी को जोड़ने से बच सकते हैं वह एएमडी या कॉमनजेएस जैसे मॉड्यूल पैटर्न का उपयोग करके वैश्विक दायरा। जब आप इनमें से किसी एक का उपयोग करते हैं, तो प्रत्येक टाइपस्क्रिप्ट फ़ाइल को बाहरी मॉड्यूल माना जाता है और इसे वैश्विक दायरे से बाहर रखा जाता है।

यह उदाहरण उदाहरण के प्रयोजनों के लिए कोणीय को हटा देता है, लेकिन जब RequJS define विधि को वैश्विक रूप से जोड़ता है, तो आपके किसी भी कोड को इस दायरे में नहीं रखा जाता है।

MyModule.ts

export class myController { 
    constructor($scope) { 
     $scope.myNewProperty = "Bob"; 
    } 
} 

app.ts

import MyModule = require('MyModule'); 

var controller = new MyModule.myController(''); 

एचटीएमएल

<script src="Scripts/require.js" data-main="app.js"></script> 

क्या app.js लगता है:

define(["require", "exports", 'MyModule'], function (require, exports, MyModule) { 
    var controller = new MyModule.myController(''); 
}); 

वैकल्पिक रूप से ... जैसा कि आप जानते हैं ... आप अभी भी जावास्क्रिप्ट का उपयोग कर इसे लागू कर सकते हैं, यदि आप चाहें तो पहले से ही उपयोग कर रहे हैं - आपको अभी भी ऑटो-पूर्णता और टाइपिंग जांच मिल जाएगी, जो कि प्रमुख लाभ हैं, भले ही आप ' कक्षाएं नहीं मिल रही है।

+0

उत्तर देने के लिए धन्यवाद। मैं एएमडी (आवश्यकताजेएस) या कॉमनजेएस से परिचित नहीं हूं। इसके लिए एक अतिरिक्त लाइब्रेरी जोड़ना एक जटिलता थी जिसे मैं टालने की उम्मीद कर रहा था (कुछ टीएस समाधान की उम्मीद कर रहा हूं) ... लेकिन मैं जांच करूंगा। – user603563

+0

यह निर्भर करता है कि आप वैश्विक दायरे से कितना दूर रहना चाहते हैं। आप एक मॉड्यूल का उपयोग कर सकते हैं और इसे प्रत्येक मॉड्यूल के साथ बढ़ा सकते हैं और यह "वैश्विक क्षेत्र में केवल एक चीज" होगी, जो आपको स्वीकार्य हो सकता है। यह जवाब "वैश्विक दायरे में कोई कोड नहीं है" उत्तर है। – Fenton

1

जोश सही है। मॉड्यूल का प्रयोग करें। साथ ही, शायद गड़बड़ी या गल्प यूग्लीफायर का उपयोग करना एक अच्छा विचार है जिसमें आपके पूरे एप्लिकेशन को बिल्ड समय पर बंद करने में एक विकल्प है।

यह आपके प्रश्न का उत्तर नहीं है, लेकिन एक सुझाव है।

एक तरफ ध्यान दें पर, नियंत्रक

module myModule { 

    // We export the class so that we can access its interface in tests. 
    // The build time gulp or grunt uglify will wrap our app in a closure 
    // so that none of these exports will be available outside the app. 
    export class MyController { 

     myNewProperty = "bob"; 

     // Next we will use Angulars $inject annotation to inject a service 
     // into our controller. We will make this private so that it can be 
     // used internally. 
     static $inject = ['someService']; 
     constructor(private someService: ng.ISomeService) {} 

     // we can access our class members using 'this' 
     doSomething() { 
      this.someService.doSomething(this.myNewProperty); 
     } 

    } 

    angular.module('app').controller('MyController', MyController); 

} 

इस वाक्य रचना आप controllerAs वाक्य रचना का प्रयोग करेंगे के साथ साथ के लिए इस वाक्य पर विचार करें।

0

बस के रूप में जावास्क्रिप्ट में, आप पूरी तरह से नाम स्थान प्रदूषण एक तुरंत लागू समारोह अभिव्यक्ति के अंदर अपने घोषणाओं लपेटकर द्वारा बच सकते हैं।

तो मूल जावास्क्रिप्ट:

(function() { 
    class MyController { 
    static $inject = ['$scope']; 
    contructor($scope: ng.IScope & { myNewProperty: string }) { 
     $scope.myNewProperty = 'Bob'; 
    } 
    } 

    angular.module('myModule', []) 
    .controller('MyController', MyController); 
})(); 

ध्यान दें कि यह आसपास के दायरे में कोई नाम का परिचय:

(function() { 
    var app = angular.module('myModule', []); 
    app.controller('myController', ['$scope', 
    function ($scope) { 
     $scope.myNewProperty = "Bob"; 
    } 
    ]); 
})(); 

निम्नलिखित टाइपप्रति हो जाता है। असल में, मूल जावास्क्रिप्ट पूरी तरह से टाइपस्क्रिप्ट मान्य है, लेकिन यह टाइपस्क्रिप्ट का लाभ नहीं लेता है। यह भी ध्यान दें कि मैंने शैली के लिए थोड़ा संपादित किया है।

किसी भी दर पर, यदि आप मॉड्यूल लोडर जैसे मॉड्यूल लोडर के साथ मॉड्यूल का उपयोग नहीं कर रहे हैं जैसे कि RequJS, SystemJS, या आपके पास क्या है, तो आप अभी भी कोशिश किए गए और सही आईआईएफई पैटर्न का पालन करके नेमस्पेस प्रदूषण से बच सकते हैं। यह मेरी सिफारिश है।

संबंधित मुद्दे