AngularJS에서 서비스 호출에 상대 경로 사용
테스트 서버에 배포 할 때까지 잘 작동하는 다음 코드가 있습니다.
$scope.getUserList = function (userName) {
$http({
method: "get",
url: "GetUserList",
params: { userName: userName }
}).
success(function (data) {
$scope.users = data;
}).
error(function () {
alert("Error getting users.");
문제는 가상 디렉터리에 배포했으며 아래 호출이 서버 루트에서 GetUserList를 누르려고한다는 것입니다. 이것은 말이되며 나는 그것을 고치는 여러 가지 방법을 알고 있습니다.
내가 알고 싶은 것은 Angular에서 이식 가능하고 유지 관리 할 수있는 방식으로 서비스 URL을 참조 하는 올바른 방법입니다.
머리에 HTML 기본 태그를 사용하고 이것과 관련된 모든 경로를 코딩하는 것이 좋습니다. 예를 들어 ASP.NET에서는 사이트의 루트 경로 일 수도 있고 아닐 수도있는 응용 프로그램의 기반에 대한 참조를 가져올 수 있으므로 기본 태그를 사용하면 도움이됩니다. 보너스 : 다른 모든 자산에도 적용됩니다.
다음과 같은 기본 경로를 가질 수 있습니다.
<base href="/application_root/" />
... "foo / bar.html"과 같은 링크는 실제로 /application_root/foo/bar.html이됩니다.
내가 사용하는 또 다른 접근 방식은 헤더에 명명 된 링크를 넣는 것입니다. 한 위치에는 API 루트가 있고 다른 위치에는 디렉티브 템플릿 루트가있는 경우가 많습니다. 머리에 다음과 같은 태그를 추가합니다.
<link id="linkApiRoot" href="/application_root/api/"/>
<link id="linkTemplateRoot" href="/application_root/Content/Templates/"/>
... 모듈에서 $ provide를 사용하여 링크 href를 가져 와서 다음과 같은 서비스 및 지시문에 노출합니다.
angular.module("app.services", [])
.config(["$provide", function ($provide) {
$provide.value("apiRoot", $("#linkApiRoot").attr("href"));
}]);
... 다음과 같은 서비스에 삽입합니다.
angular.module("app.services").factory("myAdminSvc", ["apiRoot", function (apiRoot) {
var apiAdminRoot = apiRoot + "admin/";
...
그래도 내 의견입니다. 응용 프로그램에 대해 가장 덜 복잡한 작업을 수행하십시오.
응용 프로그램을 전달할 수있는 전역 구성을 포함하는 모듈을 정의하는 것이 좋습니다.
// Module specific configuration
angular.module('app.config')
.value('app.config', {
basePath: '/' // Set your base path here
});
그런 다음 AngularJS 종속성 주입 덕분에 애플리케이션 내 어디서나 액세스 할 수 있습니다.
// Make sure your config is included in your module
angular.module('app', ['app.config']);
// Access your config e.g. in a controller
angular.module('app')
.controller('TestCtrl', ['$scope','app.config', function($scope, config){
// Use config base path to assemble url
$scope.url = config.basePath + 'GetUserList';
...
}]);
Whenever the base path changes (e.g. when you change to another server or host), you just need to change it in your global config and you're done.
I wasn't able to use <base>
tag since my application was created in a popup dynamically from another origion. I was considering the others option in this thread to use something like a basePath variable and use it in every $http, ng-src, templateUrl
etc
But that was a bit overhead, built a interceptor that change every url before a xhr is made
var app = angular.module("myApp", []);
app.config(["$httpProvider", function($httpProvider) {
$httpProvider.interceptors.push('middleware');
}]);
app.factory('middleware', function() {
return {
request: function(config) {
// need more controlling when there is more than 1 domain involved
config.url = "//example.com/api/" + config.url
return config;
}
};
});
app.controller("Ctrl", ["$http", function($http) {
$http.get("books"); // actually requestUrl = http://example.com/api/books
}])
And html aswell
<div ng-include src="'view'">
<!-- actually src = http://example.com/api/view -->
</div>
But i do recommend to use <base>
tag instead unless you are using window.popup()
Use the $location service - it will return your path, the hash, the server address.. Everything you need! Your call would be to $location.path()+"/GetUserList"
or something similar.
See here: http://docs.angularjs.org/guide/dev_guide.services.$location
I had a similar problem I solve it with the just one line of code in my MVC page
<base href="~/" />
The accepted answer helped me. I'm using Angular served up my an MVC app. I took one extra step so that my baseUrl could be used within my angular controllers for web api calls or for accessing templates.
Using ng-init to set the baseUrl (from a server side populated value)
<html ng-app="app" ng-controller="AppController">
<head>
<base href="{{baseUrl}}" ng-init="baseUrl = '@Model.BaseUrl'" />
</head>
Angular controller
$scope.manageCustomerGroups = function () {
openDialog($scope.baseUrl + 'content/templates/customerGroups.html');
}
A simple way, I'm using ASP.NET Razor (Web MVC), so I get the Application path and make it as the base of app.
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Title</title>
<meta name="description" content="">
@{ var appPath = Request.ApplicationPath.ToString();
if (!appPath.EndsWith("/")) {
appPath = appPath + "/";
}
}
<base href="@appPath" />
I would just make all URL relative.
url: "../GetUserList",
instead
url: "GetUserList",
Hard coding for the, <base href="/application_root/" />
dose not sound good idea to me as you might need to change this environment to environment, and has dependency over virtual directory name.
In the ng-init function pass a parameter that contains the value the virtual directory (int ASP.NET stored in Request.ApplicationPath).
<div ng-controller="ControllerName" ng-init="init('@Request.ApplicationPath')">
Inside the angular controller, use this value as prefix of URL in every http call. You can use this function to combine the paths
function combinePath(path1, path2) {
if (path1 == null) {
return path2;
}
var last = path1.slice(-1);
var first = path2.charAt(0);
if (last == '/' && first == '/') {
path1 = path1.substring(0, path1.length - 1);
}
return path1 + path2;
}
참고URL : https://stackoverflow.com/questions/17011616/using-a-relative-path-for-a-service-call-in-angularjs
'Program Tip' 카테고리의 다른 글
대문자를 소문자로 변환하는 방법 (0) | 2020.11.13 |
---|---|
git pull 후 코드 변경 사항을 보는 방법은 무엇입니까? (0) | 2020.11.13 |
정당화 내용과 정렬 항목의 차이점은 무엇입니까? (0) | 2020.11.13 |
Java에 복사 생성자가없는 이유는 무엇입니까? (0) | 2020.11.13 |
Nokogiri 문서를 Ruby Hash로 변환 (0) | 2020.11.13 |