필요한 경우에만 모듈을 동적으로 주입합니다.
Require.js와 Angular.js를 조합하여 사용하고 있습니다.
에 따라서는 큰 하지 않은 외부 의존관계가 합니다.FirstController에는 Angular UI Codemirror가 필요합니다.적어도 135kb가 추가됩니다.
require([
"angular",
"angular.ui.codemirror" // requires codemirror itself
], function(angular) {
angular.module("app", [ ..., "ui.codemirror" ]).controller("FirstController", [ ... ]);
});
Angular를 행복하게 하기 위해 페이지가 로드될 때마다 디렉티브와 Codemirror lib를 포함할 필요는 없습니다.
그래서 지금 당장 관제탑을 장착하고 있는 겁니다 여기서처럼 경로가 맞았을 때만요
하지만 제가 뭔가 필요한 게 있을 때
define([
"app",
"angular.ui.codemirror"
], function(app) {
// ui-codemirror directive MUST be available to the view of this controller as of now
app.lazy.controller("FirstController", [
"$scope",
function($scope) {
// ...
}
]);
});
을 지시하려면 어떻게 해야 요?ui.codemirror모듈(또는 다른 모듈)을 사용할 수 있습니까?
외부 종속성의 코드를 수정하는 것이 아니라면, 이것이 해킹적인 방법인지는 상관없습니다.
도움이 되는 경우:Angular 1.2.0을 실행하고 있습니다.
저는 얼마 전부터 requiresj+Angular를 믹스하려고 하고 있습니다.인라인 코드나 핀들에 비해 스코프가 너무 커서 지금까지의 노력으로 Github(Angular-require-lazy)에서 작은 프로젝트를 발표했습니다.이 프로젝트에서는 다음 사항을 시연합니다.
- AngularJS 모듈이 느리게 로드됩니다.
- 디렉티브도 로딩이 느릴 수 있습니다.
- "모듈" 검출과 메타데이터 메커니즘이 있습니다(다른 애완견 프로젝트: require-lazy 참조).
- 애플리케이션이 번들로 자동으로 분할됩니다(즉, r.js를 사용한 빌드).
어떻게 하면 좋을까요?
- 「」:
$controllerProvider,$compileProvider합니다.config기능(agularjs-requirejs-lazy-controller에서 처음 접한 기술). - 후 " " "
angular로딩이 느린 모듈을 처리할 수 있는 자체 래퍼로 대체되었습니다. - 인젝터가 캡처되어 약속으로 제공됩니다.
- AMD 모듈은 Angular 모듈로 변환할 수 있습니다.
이 실장에서는 Angular 모듈(적어도 사용하고 있는ng-grid :)을 느리게 로드할 수 있으며 외부 라이브러리를 변경하지 않습니다.
코멘트/의견은 대환영입니다.
(이 점은 동적(EDIT)을 하지 않는다는 require()따라서 r.discl(및 내 요구조건 프로젝트)을 사용하여 구축할 수 있습니다.그 외에는 다양한 솔루션에서 아이디어가 다소 수렴되어 있습니다.
모두 행운을 빌어요!
주의: Nikos Paraskevopoulos의 솔루션을 사용합니다.신뢰성이 높고(사용하고 있습니다), 예도 많이 있습니다.
네, 이 답변에 대한 간단한 도움을 받아 드디어 이 문제를 해결하는 방법을 알아냈습니다.
내가 질문에서 말했듯이, 이것은 매우 진부한 방법이 되었다. 각각의 할 수 있습니다._invokeQueue앱 모듈의 컨텍스트에서 종속 모듈의 배열입니다.
이와 같습니다(모듈에서 더 주의하세요).익스텐더 기능을 사용하세요).
define([ "angular" ], function( angular ) {
// Returns a angular module, searching for its name, if it's a string
function get( name ) {
if ( typeof name === "string" ) {
return angular.module( name );
}
return name;
};
var moduleExtender = function( sourceModule ) {
var modules = Array.prototype.slice.call( arguments );
// Take sourceModule out of the array
modules.shift();
// Parse the source module
sourceModule = get( sourceModule );
if ( !sourceModule._amdDecorated ) {
throw new Error( "Can't extend a module which hasn't been decorated." );
}
// Merge all modules into the source module
modules.forEach(function( module ) {
module = get( module );
module._invokeQueue.reverse().forEach(function( call ) {
// call is in format [ provider, function, args ]
var provider = sourceModule._lazyProviders[ call[ 0 ] ];
// Same as for example $controllerProvider.register("Ctrl", function() { ... })
provider && provider[ call[ 1 ] ].apply( provider, call[ 2 ] );
});
});
};
var moduleDecorator = function( module ) {
module = get( module );
module.extend = moduleExtender.bind( null, module );
// Add config to decorate with lazy providers
module.config([
"$compileProvider",
"$controllerProvider",
"$filterProvider",
"$provide",
function( $compileProvider, $controllerProvider, $filterProvider, $provide ) {
module._lazyProviders = {
$compileProvider: $compileProvider,
$controllerProvider: $controllerProvider,
$filterProvider: $filterProvider,
$provide: $provide
};
module.lazy = {
// ...controller, directive, etc, all functions to define something in angular are here, just like the project mentioned in the question
};
module._amdDecorated = true;
}
]);
};
// Tadaaa, all done!
return {
decorate: moduleDecorator
};
});
이 작업이 완료되면 예를 들어 다음과 같은 작업을 수행해야 합니다.
app.extend( "ui.codemirror" ); // ui.codemirror module will now be available in my application
app.controller( "FirstController", [ ..., function() { });
의 열쇠는 모든 이 '''모듈''이라는 입니다.app모듈도 느린 로딩 모듈이어야 합니다.이는 각도가 $injector 서비스에 사용하는 공급자 및 인스턴스는 비공개이며 초기화가 완료된 후 새 모듈을 등록하는 방법을 노출하지 않기 때문입니다.
이 '을 각각 편집한 후(에 컨트롤러, , 콜을 하여 " " " " " 를 입니다. 'appModules.js' 파일에 있음), 컨트롤러, 디렉티브, 공장 호출을 각각 편집하여 사용하는 것입니다.app.lazy.{same call}★★★★★★ 。
그 후, 앱 루트가 어떻게 로딩되어 있는지 살펴봄으로써 링크된 샘플 프로젝트를 계속 진행할 수 있습니다('appRoutes.js' 파일에는 그 방법이 나와 있습니다).
이게 도움이 될지는 모르겠지만 행운을 빌어요.
이를 위한 지침이 있습니다.
https://github.com/AndyGrom/loadOnDemand
예:
<div load-on-demand="'module_name'"></div>
기존의 게으른 부하 기술의 문제점은 내가 하고 싶은 일을 스스로 해낸다는 것이다.
예를 들어 requirejs를 사용하여 다음 번호로 전화하겠습니다.
require(['tinymce', function() {
// here I would like to just have tinymce module loaded and working
});
하지만 그런 식으로는 안 되지 왜?내가 알기로는 앵글JS는 모듈을 '미래에 로드될 것'으로 표시하기만 하면 됩니다.예를 들어, 조금 기다리면 동작합니다.사용할 수 있습니다.위의 함수에서는 loadPendingModules()와 같은 함수를 호출하고 싶습니다.
프로젝트에서는 심플한 프로바이더('lazyLoad')를 작성했습니다.이 프로바이더는 이것만 하고 나머지는 아무것도 하지 않습니다.따라서 모듈을 완전히 로드해야 할 경우 다음 작업을 수행할 수 있습니다.
myApp.controller('myController', ['$scope', 'lazyLoad', function($scope, lazyLoad) {
// ........
$scope.onMyButtonClicked = function() {
require(['tinymce', function() {
lazyLoad.loadModules();
// and here I can work with the modules as they are completely loaded
}]);
};
// ........
});
다음은 소스 파일(MPL 라이선스) 링크입니다.https://github.com/lessmarkup/less-markup/blob/master/LessMarkup/UserInterface/Scripts/Providers/lazyload.js
샘플 코드를 보내드립니다.저는 잘 되고 있어요.확인 부탁드립니다.
var myapp = angular.module('myapp', ['ngRoute']);
/* Module Creation */
var app = angular.module('app', ['ngRoute']);
app.config(['$routeProvider', '$controllerProvider', function ($routeProvider, $controllerProvider) {
app.register = {
controller: $controllerProvider.register,
//directive: $compileProvider.directive,
//filter: $filterProvider.register,
//factory: $provide.factory,
//service: $provide.service
};
// so I keep a reference from when I ran my module config
function registerController(moduleName, controllerName) {
// Here I cannot get the controller function directly so I
// need to loop through the module's _invokeQueue to get it
var queue = angular.module(moduleName)._invokeQueue;
for (var i = 0; i < queue.length; i++) {
var call = queue[i];
if (call[0] == "$controllerProvider" &&
call[1] == "register" &&
call[2][0] == controllerName) {
app.register.controller(controllerName, call[2][1]);
}
}
}
var tt = {
loadScript:
function (path) {
var result = $.Deferred(),
script = document.createElement("script");
script.async = "async";
script.type = "text/javascript";
script.src = path;
script.onload = script.onreadystatechange = function (_, isAbort) {
if (!script.readyState || /loaded|complete/.test(script.readyState)) {
if (isAbort)
result.reject();
else {
result.resolve();
}
}
};
script.onerror = function () { result.reject(); };
document.querySelector(".shubham").appendChild(script);
return result.promise();
}
}
function stripScripts(s) {
var div = document.querySelector(".shubham");
div.innerHTML = s;
var scripts = div.getElementsByTagName('script');
var i = scripts.length;
while (i--) {
scripts[i].parentNode.removeChild(scripts[i]);
}
return div.innerHTML;
}
function loader(arrayName) {
return {
load: function ($q) {
stripScripts(''); // This Function Remove javascript from Local
var deferred = $q.defer(),
map = arrayName.map(function (obj) {
return tt.loadScript(obj.path)
.then(function () {
registerController(obj.module, obj.controller);
})
});
$q.all(map).then(function (r) {
deferred.resolve();
});
return deferred.promise;
}
};
};
$routeProvider
.when('/first', {
templateUrl: '/Views/foo.html',
resolve: loader([{ controller: 'FirstController', path: '/MyScripts/FirstController.js', module: 'app' },
{ controller: 'SecondController', path: '/MyScripts/SecondController.js', module: 'app' }])
})
.when('/second', {
templateUrl: '/Views/bar.html',
resolve: loader([{ controller: 'SecondController', path: '/MyScripts/SecondController.js', module: 'app' },
{ controller: 'A', path: '/MyScripts/anotherModuleController.js', module: 'myapp' }])
})
.otherwise({
redirectTo: document.location.pathname
});
}])
HTML 페이지:
<body ng-app="app">
<div class="container example">
<!--ng-controller="testController"-->
<h3>Hello</h3>
<table>
<tr>
<td><a href="#/first">First Page </a></td>
<td><a href="#/second">Second Page</a></td>
</tr>
</table>
<div id="ng-view" class="wrapper_inside" ng-view>
</div>
<div class="shubham">
</div>
</div>
언급URL : https://stackoverflow.com/questions/18591966/inject-module-dynamically-only-if-required
'source' 카테고리의 다른 글
| 도커를 통한 MongoDB 인증 활성화 방법 (0) | 2023.03.08 |
|---|---|
| 기본 Next.js 개발 서버를 사용하는 백엔드의 프록시 (0) | 2023.03.08 |
| expo 앱을 로드할 수 없음: 문제가 발생했습니다. (0) | 2023.03.08 |
| React 기능 컴포넌트 내에서 비동기/대기 사용 (0) | 2023.03.08 |
| html 코드에서 json 파일을 사용하는 방법 (0) | 2023.03.08 |