저는 몇 가지 다른 위치에서 사용될 각도 지시문을 만들고 있습니다. 지시문이 사용 된 앱의 파일 구조를 항상 보장 할 수는 없지만 사용자가 동일한 폴더에 directive.js
및 directive.html
(실제 파일 이름이 아님) 를 넣도록 강제 할 수 있습니다 .
페이지가를 평가할 때는 자체에 상대적인 directive.js
것으로 간주합니다 templateUrl
. 을 파일에 templateUrl
상대적으로 설정할 수 directive.js
있습니까?
또는 지시문 자체에 템플릿을 포함하는 것이 좋습니다.
다른 상황에 따라 다른 템플릿을로드하고 싶을 수 있으므로 업데이트하는 대신 상대 경로를 사용하는 것이 좋습니다. directive.js
답변
현재 실행중인 스크립트 파일은 항상 스크립트 배열의 마지막 파일이므로 해당 경로를 쉽게 찾을 수 있습니다.
// directive.js
var scripts = document.getElementsByTagName("script")
var currentScriptPath = scripts[scripts.length-1].src;
angular.module('app', [])
.directive('test', function () {
return {
templateUrl: currentScriptPath.replace('directive.js', 'directive.html')
};
});
스크립트 이름이 무엇인지 확실하지 않은 경우 (예 : 여러 스크립트를 하나로 묶는 경우) 다음을 사용합니다.
return {
templateUrl: currentScriptPath.substring(0, currentScriptPath.lastIndexOf('/') + 1)
+ 'directive.html'
};
참고 : 클로저가 사용되는 경우 다음과 같이 currentScript가 올바른 시간에 평가되도록 코드가 외부에 있어야합니다.
// directive.js
(function(currentScriptPath){
angular.module('app', [])
.directive('test', function () {
return {
templateUrl: currentScriptPath.replace('directive.js', 'directive.html')
};
});
})(
(function () {
var scripts = document.getElementsByTagName("script");
var currentScriptPath = scripts[scripts.length - 1].src;
return currentScriptPath;
})()
);
답변
지시문에 다른 시간에 다른 템플릿을 제공하고 싶다고 말했듯이 템플릿 자체가 특성으로 지시문에 전달되도록 허용하지 않는 이유는 무엇입니까?
<div my-directive my-template="template"></div>
그런 다음 $compile(template)(scope)
지시문 내부 와 같은 것을 사용 하십시오.
답변
Alon Gubkin 의 답변 외에도 즉시 호출 된 함수 표현식을 사용하여 상수를 정의하여 스크립트 경로를 저장하고 지시문에 삽입하는 것이 좋습니다.
angular.module('app', [])
.constant('SCRIPT_URL', (function () {
var scripts = document.getElementsByTagName("script");
var scriptPath = scripts[scripts.length - 1].src;
return scriptPath.substring(0, scriptPath.lastIndexOf('/') + 1)
})())
.directive('test', function(SCRIPT_URL) {
return {
restrict : 'A',
templateUrl : SCRIPT_URL + 'directive.html'
}
});
답변
이 코드는 route.js라는 파일에 있습니다.
다음은 나를 위해 작동하지 않았습니다.
var scripts = document.getElementsByTagName("script")
var currentScriptPath = scripts[scripts.length-1].src;
var baseUrl = currentScriptPath.substring(0, currentScriptPath.lastIndexOf('/') + 1);
다음은 수행했습니다.
var bu2 = document.querySelector("script[src$='routes.js']");
currentScriptPath = bu2.src;
baseUrl = currentScriptPath.substring(0, currentScriptPath.lastIndexOf('/') + 1);
내 테스트는 require to lazy load angular 사용에 대한 다음 블로그를 기반으로합니다.
http://ify.io/lazy-loading-in-angularjs/
require.js는 requireConfig 부트 스트랩을 낳습니다.
requireConfig는 각도 app.js를 낳습니다.
각도 app.js가 내 routes.js를 낳습니다.
revel 웹 프레임 워크와 asp.net mvc에서 동일한 코드를 제공했습니다. revel document.getElementsByTagName ( “script”)에서 내 routes.js가 아닌 필요한 부트 스트랩 js 파일에 대한 경로를 생성했습니다. ASP.NET MVC에서는 디버깅 세션 중에 배치되는 Visual Studio의 삽입 된 브라우저 링크 스크립트 요소에 대한 경로를 생성했습니다.
이것은 내 작업 route.js 코드입니다.
define([], function()
{
var scripts = document.getElementsByTagName("script");
var currentScriptPath = scripts[scripts.length-1].src;
console.log("currentScriptPath:"+currentScriptPath);
var baseUrl = currentScriptPath.substring(0, currentScriptPath.lastIndexOf('/') + 1);
console.log("baseUrl:"+baseUrl);
var bu2 = document.querySelector("script[src$='routes.js']");
currentScriptPath = bu2.src;
console.log("bu2:"+bu2);
console.log("src:"+bu2.src);
baseUrl = currentScriptPath.substring(0, currentScriptPath.lastIndexOf('/') + 1);
console.log("baseUrl:"+baseUrl);
return {
defaultRoutePath: '/',
routes: {
'/': {
templateUrl: baseUrl + 'views/home.html',
dependencies: [
'controllers/HomeViewController',
'directives/app-style'
]
},
'/about/:person': {
templateUrl: baseUrl + 'views/about.html',
dependencies: [
'controllers/AboutViewController',
'directives/app-color'
]
},
'/contact': {
templateUrl: baseUrl + 'views/contact.html',
dependencies: [
'controllers/ContactViewController',
'directives/app-color',
'directives/app-style'
]
}
}
};
});
이것은 Revel에서 실행할 때의 콘솔 출력입니다.
currentScriptPath:http://localhost:9000/public/ngApps/1/requireBootstrap.js routes.js:8
baseUrl:http://localhost:9000/public/ngApps/1/ routes.js:10
bu2:[object HTMLScriptElement] routes.js:13
src:http://localhost:9000/public/ngApps/1/routes.js routes.js:14
baseUrl:http://localhost:9000/public/ngApps/1/
내가 한 또 다른 좋은 일은 require 구성을 활용하고 몇 가지 사용자 정의 구성을 넣는 것입니다. 즉 추가
customConfig: { baseRouteUrl: '/AngularLazyBaseLine/Home/Content' }
그런 다음 route.js 내부에서 다음 코드를 사용하여 가져올 수 있습니다.
var requireConfig = requirejs.s.contexts._.config;
console.log('requireConfig.customConfig.baseRouteUrl:' + requireConfig.customConfig.baseRouteUrl);
때로는 baseurl을 미리 정의해야하고 때로는 동적으로 생성해야합니다. 상황에 맞는 선택.
답변
어떤 사람들은 약간 “해키”라고 제안 할 수도 있지만, 한 가지 방법 만있을 때까지는 모든 것이 해키가 될 것이라고 생각합니다.
나는 또한 이것을하는 데 많은 운이 좋았습니다.
angular.module('ui.bootstrap', [])
.provider('$appUrl', function(){
this.route = function(url){
var stack = new Error('dummy').stack.match(new RegExp(/(http(s)*\:\/\/)[^\:]+/igm));
var app_path = stack[1];
app_path = app_path.slice(0, app_path.lastIndexOf('App/') + 'App/'.length);
return app_path + url;
}
this.$get = function(){
return this.route;
}
});
그런 다음 앱에 모듈을 포함시킨 후 애플리케이션에서 코드를 사용할 때.
앱 구성 기능에서 :
.config(['$routeProvider', '$appUrlProvider', function ($routeProvider, $appUrlProvider) {
$routeProvider
.when('/path:folder_path*', {
controller: 'BrowseFolderCntrl',
templateUrl: $appUrlProvider.route('views/browse-folder.html')
});
}]);
그리고 앱 컨트롤러에서 (필요한 경우) :
var MyCntrl = function ($scope, $appUrl) {
$scope.templateUrl = $appUrl('views/my-angular-view.html');
};
새로운 자바 스크립트 오류를 생성하고 스택 추적을 가져옵니다. 그런 다음 모든 URL을 구문 분석합니다 (호출 회선 / 문자 번호 제외).
그런 다음 코드가 실행되는 현재 파일이 될 배열의 첫 번째 파일을 꺼낼 수 있습니다.
이는 코드를 중앙 집중화 한 다음 [1]
배열에서 두 번째 ( )를 꺼내 호출 파일 위치를 가져 오는 경우에도 유용합니다.
답변
여러 사용자가 지적했듯이 관련 경로는 정적 파일을 빌드 할 때 도움이되지 않으므로 그렇게하는 것이 좋습니다.
Angular에는 $ templateCache 라는 멋진 기능이 있습니다.이 기능은 템플릿 파일 을 어느 정도 캐시하고 다음에 angular가 실제로 요청하는 대신 캐시 된 버전을 제공합니다. 다음은이를 사용하는 일반적인 방법입니다.
module = angular.module('myModule');
module.run(['$templateCache', function($templateCache) {
$templateCache.put('as/specified/in/templateurl/file.html',
'<div>blabla</div>');
}]);
})();
따라서 이러한 방식으로 상대 URL 문제를 해결하고 성능을 높일 수 있습니다.
물론 우리는 (반응과는 대조적으로) 별도의 템플릿 html 파일을 가지고 있다는 생각을 좋아하므로 위의 내용 자체는 좋지 않습니다. 여기에 모든 템플릿 html 파일을 읽고 위와 같은 js를 구성 할 수있는 빌드 시스템이 있습니다.
grunt, gulp, webpack을위한 몇 가지 html2js 모듈이 있으며 이것이 그이면의 주요 아이디어입니다. 저는 개인적 으로 gulp를 많이 사용하므로 특히 gulp-ng-html2js를 매우 쉽게 사용하기 때문에 특히 좋아 합니다.