2015-11-03 13 views
10

मुझे लगता है कि एक दीवार मारा है मैं टूटने में सक्षम नहीं हूं। मैं कोणीय + टाइपस्क्रिप्ट का उपयोग कर रहा हूं, और इसे requjs के साथ काम करना चाहता हूं। कई कोणीय ऐप्स परिभाषित किए गए हैं जो शरीर पर डेटा-ऐप-नाम विशेषता पर निर्भर होते हैं।Requjs + (बहु) कोणीय + टाइपस्क्रिप्ट

फ़ोल्डर संरचना (सरलीकृत):

|- Libs 
    |- angular 
    |- some-plugin 
    |- angular-some-plugin // Exposes an angular.module("ngSomePlugin") 
    |- require.js 
|- Common 
    |- Common.ts // Exposes an angular.module("common") 
|- App1 
    |- Controllers 
     |- SomeController.ts 
     |- SomeOtherController.ts 
    |- Services 
     |- SomeService.ts 
    |- Main.ts 
    |- App.ts 
|- App2 
    // same as above 
|- AppX 
    // same as above 
|- Index.html 
|- Main.ts 

सामग्री:

Index.html:

// All these attributes are set dynamically server-side 
<body id="ng-app-wrapper" data-directory="App1" data-app-name="MyApp"> 
    <script src="Libs/require.js" data-main="Main"></script> 
</body> 

Main.ts: APP1 में

console.log("Step 1: Main.js"); 

requirejs.config({ 
    paths: { 
     "angular": "Libs/angular/angular", 
     "common": "Common/common" 
    }, 
    shim: { 
     "angular": { 
      exports: "angular" 
     } 
    } 
}); 

require(["angular"], (angular: angular.IAngularStatic) => { 
    angular.element(document).ready(function() { 

     var $app = angular.element(document.getElementById("ng-app-wrapper")); 
     var directory = $app.data("directory"); 
     var appName = $app.data("app-name"); 

     requirejs.config({ 
      paths: { 
       "appMain": directory + "/Main" 
      } 
     }); 

     require([ 
      'common', 
      'appMain' 
     ], function() { 
      console.log("Step 5: App1/Main.js loaded"); 
      console.log("Step 6: Bootstrapping app: " + appName); 
      angular.bootstrap($app, [appName]); 
     }); 
    }); 
}); 

Main.ts :

console.log("Step 2: App1/Main.js"); 

requirejs.config({ 
    paths: { 
     "app": "App1/App", 
     "somePlugin": "Libs/some-plugin/some-plugin", // This is an AMD module 
     "ngSomePlugin": "Libs/angular-some-plugin/angular-some-plugin" 
    }, 
    shim: { 
     "ngSomePlugin": { 
      exports: "ngSomePlugin", 
      deps: ["somePlugin"] 
     } 
    } 
}); 

define([ 
    "app" 
],() => { 
    console.log("Step 4: App.js loaded"); 
}); 

APP1/App.ts:

console.log("Step 3: App.js"); 

import SomeController = require("App1/Controllers/SomeController"); 
import SomeOtherController = require("App1/Controllers/SomeOtherController"); 
import SomeService = require("App1/Services/SomeService"); 

define([ 
    "angular", 
    "ngSomePlugin" 
], (angular: angular.IAngularStatic) => { 

    // This isn't called, so obviously executed to late 
    console.log("Defining angular module MyApp"); 

    angular.module("MyApp", ["common", "ngSomePlugin"]) 
     .controller("someCtrl", SomeController.SomeController) 
     .controller("someOtherCtrl", SomeOtherController.SomeOtherController) 
     .service("someService", SomeService.SomeService) 
     ; 
}); 

हालांकि यह अच्छे पुराने त्रुटि के साथ, तोड़ने के लिए लगता है: Uncaught त्रुटि: [$ इंजेक्टर: nomod] मॉड्यूल 'MyApp' उपलब्ध नहीं है! आप या तो मॉड्यूल नाम गलत वर्तनी या इसे लोड करने के लिए भूल गए हैं।

प्रश्न 1:

क्या मैं गलत यहाँ कर रहा हूँ? मैं अपने ऐप को बूटस्ट्रैप करने से पहले angular.module() कॉल कैसे कर सकता हूं?

यह console.logs है, जहां आप कोणीय देख सकते हैं के उत्पादन में अभी तक मॉड्यूल angular.module ("MyApp") निर्धारित नहीं किया है, इसलिए इस देर से स्पष्ट रूप से करने के लिए किया जाता है: Console log

अद्यतन मैं ऐप.ट्स में कोणीय कॉल को खोल सकता हूं, इसलिए इसे किसी भी चीज की आवश्यकता नहीं है (शीर्ष पर आयात को छोड़कर)। फिर यदि मैं ऐप 1/Main.ts में शिम में ऐप जोड़ता हूं, और वहां निर्भरताएं रखती हैं तो ऐसा लगता है। क्या यह हल करने का यह एक अच्छा तरीका है?

UPDATE2 अगर मैं का उपयोग App.ts में परिभाषित करने के बजाय की आवश्यकता होती है, यह कोणीय मॉड्यूल का दृष्टांत करता है, लेकिन अभी भी यह यह bootstrap की कोशिश करता है के बाद।

प्रश्न 2:

वहाँ नीचे कस्टम विन्यास पारित करने के लिए किसी भी तरह से निर्देशिका का नाम जहां Libs हैं है, उदाहरण के लिए?

requirejs.config({ 
    paths: { 
     "appMain": directory + "/Main" 
    }, 
    config: { 
     "appMain": { 
      libsPath: "Libs/" 
     }, 
     "app": { 
      name: appName 
     } 
    } 
}); 

APP1/Main.ts:

define(["module"], (module) => { 
    var libsPath = module.config().libsPath; 
    requirejs.config({ 
     paths: { 
      "somePlugin": libsPath + "somePlugin/somePlugin" 
      // rest of paths 
     } 
    }); 

    define([ // or require([]) 
     "app" 
    ],() => {}); 
}); 

App.ts:

define([ 
    "module" 
    // others 
], (module) => { 
    angular.module(module.config().name, []); 
}); 

लेकिन इस तरह से मैं जिसके बाद काम करने के लिए नहीं मालूम था (Main.ts) की कोशिश की , तार्किक रूप से, angular.bootstrap() App.ts को लोड होने की प्रतीक्षा नहीं करता है। इसलिए कोणीय मॉड्यूल अभी तक परिभाषित नहीं किया गया है और यह बूटस्ट्रैप में विफल रहता है। ऐसा लगता है कि आप App1/Main.ts में घोंसला परिभाषित नहीं कर सकते हैं? मुझे इसे कैसे कॉन्फ़िगर करना चाहिए?

+0

मैं शक नहीं है कि 'require.config की कई परतों()' कॉल अपेक्षा के अनुरूप काम करेंगे। (साइड-प्रश्न: क्या वे करते हैं?) लेकिन चूंकि 'डेटा-निर्देशिका'/'डेटा-ऐप-नाम 'सर्वर-साइड जेनरेट किए जाते हैं, इसलिए मैं सुझाव दूंगा कि आप' requ.config() 'कॉल को गतिशील रूप से भी उत्पन्न करें। आप गतिशील रूप से भी चाहते हैं, सर्वर-साइड में उचित खंड सीधे index.html में शामिल है। वहां से, आपको एएमडी मॉड्यूल में पथों को ट्विक करने की आवश्यकता होगी। और एक sidenote: आप AMD के लिए टाइपस्क्रिप्ट के मूल समर्थन का उपयोग क्यों नहीं कर रहे हैं, यानी 'आयात Foo = आवश्यकता (' Foo ')' वाक्यविन्यास? –

+0

मैं कोणीय-एप स्तर (App.ts और अन्य सभी कोणीय घटकों में) पर 'आयात' सामान करता हूं। यदि मैं टाइपस्क्रिप्ट का उपयोग कर रहा हूं तो हर जगह आयात वाक्यविन्यास का उपयोग करना बेहतर है? मुझे नहीं लगता कि यह गैर-एएमडी तीसरे पक्ष के पुस्तकालयों पर काम करेगा? – devqon

+0

और हां, 'require.config()' की कई परतें काम करने लगती हैं :) – devqon

उत्तर

-1

1 प्रश्न से संबंधित:

APP1/App.ts में, नहीं समारोह कोणीय मॉड्यूल लौटना चाहिए यह इंजेक्ट किया जा करने के लिए।

उदाहरण के लिए।

define([ 
    "angular", 
    "ngSomePlugin" 
], (angular: angular.IAngularStatic) => { 
    return angular.module("MyApp", ["common", "ngSomePlugin"]) 
     .controller("someCtrl", SomeController.SomeController) 
     .controller("someOtherCtrl", SomeOtherController.SomeOtherController) 
     .service("someService", SomeService.SomeService) 
     ; 
}); 
+0

मुझे वास्तव में मॉड्यूल की ज़रूरत नहीं है, मुझे केवल यह सुनिश्चित करने की आवश्यकता है कि यह तत्काल है इसलिए मैं अपने एप्लिकेशन को बूटस्ट्रैप कर सकता हूं, जो केवल नाम से किया जाता है: 'angular.bootstrap ($ app, ["MyApp"]) ' – devqon

+0

और मैंने यह भी कोशिश की :) – devqon

+0

यह शरीर के निष्पादन पर निर्भर है, न कि लौटाई गई सामग्री के मूल्य पर .. – EricG

0

प्रश्न 1

अलेक्जेंडर Beletsky एक साथ बांधने requireJS और कोणीय के बारे में great article लिखा था (और के बारे में कारण है कि यह इसके लायक है)। इसमें, मुझे लगता है कि उसके पास आपके पहले प्रश्न का उत्तर है: किसी अन्य मॉड्यूल से लोड कोणीय और फिर बूटस्ट्रैपिंग कॉल करें। इस बल को जेएस को किसी भी कोड को निष्पादित करने से पहले उन मॉड्यूल के लिए निर्भरता लोड करने की आवश्यकता होती है।

इस मान लिया जाये कि है अपने main.ts

console.log("Step 1: Main.js"); 

requirejs.config({ 
    paths: { 
     "angular": "Libs/angular/angular", 
     "common": "Common/common". 
     "mainT1": "t1/main.js" 
    }, 
    shim: { 
     "angular": { 
      exports: "angular" 
     } 
    } 
}); 

बहुत t1 के मुख्य है, तो आप कर वास्तविक अनुप्रयोग में अपने अगले मॉड्यूल

requirejs(["app"], function(app) { 
    app.init(); 
}); 

यहाँ करने के लिए कॉल को समाप्त में जोड़ें और यह लोड है यकायक।

t1/main.ts

define("app-name", ['angular'], function(angular){ 

    var loader = {}; 

    loader.load = function(){ 

     var app = angular.module("app-name",[]); 

     return app; 
     } 

return loader; 

} 

अंत में, मान लें कि आपको एक मचान फ़ाइल यहाँ यह किया जाता है आप app.js कहा जाता है के लिए करते हैं। यहां आप एक ऑब्जेक्ट प्राप्त करने के लिए अनुक्रम स्थापित करेंगे जो पहले से ही कोणीय लोडिंग अनुक्रम समाप्त कर चुका है। एक बार यह पूरा हो जाने पर, फिर आप init() फ़ंक्शन में बूटस्ट्रैपिंग को कॉल करते हैं।

t1/app.js

define("app", function(require){ 
    var angular = require('angular'); 
    var appLoader = require('mainT1'); 

    var app = {} 
    app.init = function(){ 
      var loader = new appLoader(); 
      loader.load(); 
      angular.bootstrap(document, ["app-name"]); 
    } 

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