각 서비스 함수에 $scope 삽입()
서비스 대상:
angular.module('cfd')
.service('StudentService', [ '$http',
function ($http) {
// get some data via the $http
var path = 'data/people/students.json';
var students = $http.get(path).then(function (resp) {
return resp.data;
});
//save method create a new student if not already exists
//else update the existing object
this.save = function (student) {
if (student.id == null) {
//if this is new student, add it in students array
$scope.students.push(student);
} else {
//for existing student, find this student using id
//and update it.
for (i in students) {
if (students[i].id == student.id) {
students[i] = student;
}
}
}
};
내가 전화했을 때save()
수 $scope
을 얻습니다.ReferenceError: $scope is not defined
( 논리적인 순서는 save에 "save()"를 것입니다$scope
그리고, 그 때문에, 그것을 / 에 제공/주입사해야 합니다.service
이렇게 하면
.service('StudentService', [ '$http', '$scope',
function ($http, $scope) {
다음의 에러가 표시됩니다.
오류: [$injector:unpr] 알 수 없는 공급자: $scopeProvider <- $scope <- Student Service
에러내의 링크(wow that neat!)는, 그것이 인젝터에 관련하는 것으로, js 파일의 선언 순서와 관계가 있는 것을 알 수 있습니다.재주문을 시도했습니다.index.html
하지만 주입하는 방법 등 좀 더 간단한 것 같아요.
Angular-UI 및 Angular-UI 라우터 사용
$scope
컨트롤러에 주입되는 것은 (주입 가능한 기타 물질과 같은) 서비스가 아니라 Scope 객체입니다.많은 스코프 객체를 만들 수 있습니다(일반적으로 상위 스코프에서 프로토타입으로 상속됨).는 " " " 입니다.$rootScope
해서 새로 수 요.$new()
(「」를 한다)$rootScope
스코프의 목적은 앱의 프레젠테이션과 비즈니스 로직을 "접합"하는 것입니다.하는 것은 가 없다$scope
서비스를 제공하게 됩니다.
서비스는 데이터를 공유하기 위해(예를 들어, 여러 컨트롤러 간에) 사용되는 단일 개체로, 일반적으로 재사용 가능한 코드 조각을 캡슐화합니다(컨트롤러, 디렉티브, 필터, 기타 서비스 등 필요한 앱의 모든 부분에 "서비스"를 주입하여 제공할 수 있기 때문입니다).
여러 가지 방법이 도움이 될 거라고 확신해요.을 사용하다
★★★★★★★★★★★★★★★★★.StudentService
.StudentService
있는 예: 당신의 러러명명명명명명 keep keep keep((((((((((((((((((((((((((((((:$scope
그 외의 뷰/컨트롤러/필터/서비스가 그 정보에 액세스 할 필요가 있는 경우(지금 당장 액세스 할 수 없는 경우라도, 이러한 정보가 표시되기 시작해도 놀라지 말아 주세요).
의 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★)save()
방법)은 서비스 자체의 학생 배열이 갱신되고 해당 배열의 다른 모든 개체 공유도 자동으로 갱신됩니다.
상기의 어프로치에 근거해, 코드는 다음과 같습니다.
angular.
module('cfd', []).
factory('StudentService', ['$http', '$q', function ($http, $q) {
var path = 'data/people/students.json';
var students = [];
// In the real app, instead of just updating the students array
// (which will be probably already done from the controller)
// this method should send the student data to the server and
// wait for a response.
// This method returns a promise to emulate what would happen
// when actually communicating with the server.
var save = function (student) {
if (student.id === null) {
students.push(student);
} else {
for (var i = 0; i < students.length; i++) {
if (students[i].id === student.id) {
students[i] = student;
break;
}
}
}
return $q.resolve(student);
};
// Populate the students array with students from the server.
$http.get(path).then(function (response) {
response.data.forEach(function (student) {
students.push(student);
});
});
return {
students: students,
save: save
};
}]).
controller('someCtrl', ['$scope', 'StudentService',
function ($scope, StudentService) {
$scope.students = StudentService.students;
$scope.saveStudent = function (student) {
// Do some $scope-specific stuff...
// Do the actual saving using the StudentService.
// Once the operation is completed, the $scope's `students`
// array will be automatically updated, since it references
// the StudentService's `students` array.
StudentService.save(student).then(function () {
// Do some more $scope-specific stuff,
// e.g. show a notification.
}, function (err) {
// Handle the error.
});
};
}
]);
이 방법을 사용할 때 주의해야 할 점은 서비스의 어레이를 재할당하지 않는 것입니다.이 경우 다른 컴포넌트(스코프 등)는 원래 어레이를 계속 참조하고 있기 때문에 어플리케이션이 중단됩니다.
예를 들어 어레이를 클리어하려면StudentService
/* DON'T DO THAT */
var clear = function () { students = []; }
/* DO THIS INSTEAD */
var clear = function () { students.splice(0, students.length); }
이 짧은 데모도 보세요.
작은 업데이트:
중 할 수 몇 말. 단, 서비스 시 .service()
★★★★★★ 。
에 관한 문서를 인용합니다.
Angular 서비스는 서비스 팩토리에 의해 작성된 싱글톤 객체입니다.이러한 서비스 팩토리는 서비스 프로바이더에 의해 만들어지는 기능입니다.서비스 공급자는 컨스트럭터 함수입니다.인스턴스화된 경우 다음과 같은 속성을 포함해야 합니다.
$get
서비스 팩토리 기능을 유지합니다.
[...]
...그$provide
프로바이더를 하지 않고 .「 」 。
- provider(previder) - $devider를 사용하여 서비스 공급자를 등록합니다.
- constant(obj) - 공급자 및 서비스에서 액세스할 수 있는 값/개체를 등록합니다.
- value(obj) - 프로바이더가 아닌 서비스에서만 액세스할 수 있는 값/개체를 등록합니다.
- factory (fn) - 서비스 팩토리 함수 fn을 등록합니다.이 함수는 서비스 공급자오브젝트로 래핑되며 $get 속성에 지정된 팩토리 함수가 포함됩니다.
- service(class) - 서비스 공급자 개체로 래핑되는 생성자 함수($get 속성이 지정된 생성자 함수를 사용하여 새 개체를 인스턴스화하는 클래스)를 등록합니다.
기본적으로, 모든 Angular 서비스는 다음을 사용하여 등록됩니다.$provide.provider()
보다 간단한 '' , '접근' 방식, '접근' 방식, '접근' 방식, '접근' 방식, '접근' 방식, '접근' 방식 이 있습니다.service()
★★★★★★★★★★★★★★★★★」factory()
를 참조해 주세요.
이 모든 것이 서비스로 "소모"되기 때문에 어떤 방법을 사용하든 큰 차이는 없습니다(그 방법으로 서비스 요건을 충족할 수 있는 한).
★★★★★★★★★★★★★★★★★★★★★」provider
»service
»factory
져서 찾아보세요 ( 검색해 보세요을 사용하다
(이것으로 해결되길 바랍니다. 해결되지 않으면 알려주세요.)
하려고 하지 요.$scope
에서는 '실행하다', '하다', '실행하다'를 할 수 있습니다.$watch
한 후 의 을 합니다.$scope
다음은 컨트롤러에서 시도할 수 있는 예입니다.
angular.module('cfd')
.controller('MyController', ['$scope', 'StudentService', function ($scope, StudentService) {
$scope.students = null;
(function () {
$scope.$watch(function () {
return StudentService.students;
}, function (newVal, oldVal) {
if ( newValue !== oldValue ) {
$scope.students = newVal;
}
});
}());
}]);
한 가지 주의할 점은 서비스 내에서 다음 작업을 수행하기 위해students
"서비스" 오브젝트에 .this
다음과 같이 합니다.
this.students = $http.get(path).then(function (resp) {
return resp.data;
});
음 (긴 시간) ... 당신이 굳이 원한다면$scope
을 사용하다
getter/setter 서비스 생성
ngapp.factory('Scopes', function (){
var mem = {};
return {
store: function (key, value) { mem[key] = value; },
get: function (key) { return mem[key]; }
};
});
주입하여 컨트롤러 스코프를 저장합니다.
ngapp.controller('myCtrl', ['$scope', 'Scopes', function($scope, Scopes) {
Scopes.store('myCtrl', $scope);
}]);
이제 다른 서비스 내에서 스코프를 가져옵니다.
ngapp.factory('getRoute', ['Scopes', '$http', function(Scopes, $http){
// there you are
var $scope = Scopes.get('myCtrl');
}]);
서비스는 싱글톤이며 스코프가 서비스에 삽입되는 것은 논리적이지 않습니다(실제로 스코프를 서비스에 삽입할 수 없습니다).범위를 매개 변수로 전달할 수도 있지만 여러 곳에서 범위가 편집되어 디버깅이 어려워지기 때문에 이 또한 잘못된 설계 선택입니다.스코프 변수를 처리하기 위한 코드는 컨트롤러로 전송되어야 하며 서비스 콜은 서비스로 전송되어야 합니다.
서비스에서는 범위를 전혀 인식하지 못할 수 있지만 컨트롤러에서는 범위를 비동기적으로 업데이트할 수 있습니다.
문제가 발생하고 있는 것은 HTTP 콜이 비동기적으로 발신되고 있는 것을 인식하고 있지 않기 때문입니다.즉, 값을 즉시 취득할 수 없습니다.예를 들어.
var students = $http.get(path).then(function (resp) {
return resp.data;
}); // then() returns a promise object, not resp.data
이를 회피하는 간단한 방법은 콜백 기능을 제공하는 것입니다.
.service('StudentService', [ '$http',
function ($http) {
// get some data via the $http
var path = '/students';
//save method create a new student if not already exists
//else update the existing object
this.save = function (student, doneCallback) {
$http.post(
path,
{
params: {
student: student
}
}
)
.then(function (resp) {
doneCallback(resp.data); // when the async http call is done, execute the callback
});
}
.controller('StudentSaveController', ['$scope', 'StudentService', function ($scope, StudentService) {
$scope.saveUser = function (user) {
StudentService.save(user, function (data) {
$scope.message = data; // I'm assuming data is a string error returned from your REST API
})
}
}]);
폼:
<div class="form-message">{{message}}</div>
<div ng-controller="StudentSaveController">
<form novalidate class="simple-form">
Name: <input type="text" ng-model="user.name" /><br />
E-mail: <input type="email" ng-model="user.email" /><br />
Gender: <input type="radio" ng-model="user.gender" value="male" />male
<input type="radio" ng-model="user.gender" value="female" />female<br />
<input type="button" ng-click="reset()" value="Reset" />
<input type="submit" ng-click="saveUser(user)" value="Save" />
</form>
</div>
이것에 의해, 간결성을 위해서 비즈니스 로직의 일부가 삭제되었습니다.실제로 코드를 테스트한 적은 없지만, 이와 같은 것이 유효합니다.주된 개념은 컨트롤러에서 나중에 호출되는 서비스로 콜백을 전달하는 것입니다.노드를 잘 알고 있는 경우JS 이것은 같은 개념입니다.
같은 곤경에 빠졌어요.나는 다음과 같이 결론지었습니다.여기서는 scope 객체를 공장에 주입하는 것이 아니라 $http 서비스에서 반환되는 약속 개념을 사용하여 컨트롤러 자체에 $scope를 설정합니다.
(function () {
getDataFactory = function ($http)
{
return {
callWebApi: function (reqData)
{
var dataTemp = {
Page: 1, Take: 10,
PropName: 'Id', SortOrder: 'Asc'
};
return $http({
method: 'GET',
url: '/api/PatientCategoryApi/PatCat',
params: dataTemp, // Parameters to pass to external service
headers: { 'Content-Type': 'application/Json' }
})
}
}
}
patientCategoryController = function ($scope, getDataFactory) {
alert('Hare');
var promise = getDataFactory.callWebApi('someDataToPass');
promise.then(
function successCallback(response) {
alert(JSON.stringify(response.data));
// Set this response data to scope to use it in UI
$scope.gridOptions.data = response.data.Collection;
}, function errorCallback(response) {
alert('Some problem while fetching data!!');
});
}
patientCategoryController.$inject = ['$scope', 'getDataFactory'];
getDataFactory.$inject = ['$http'];
angular.module('demoApp', []);
angular.module('demoApp').controller('patientCategoryController', patientCategoryController);
angular.module('demoApp').factory('getDataFactory', getDataFactory);
}());
스코프 변수를 처리하기 위한 코드는 컨트롤러로 전송되어야 하며 서비스 콜은 서비스로 전송되어야 합니다.
요.$rootScope
사용할 목적으로$rootScope.$broadcast
★★★★★★★★★★★★★★★★★」$rootScope.$on
.
않으면 ""를 삽입하지 .$rootScope
를 참조해 주세요
- 일반적인 함정: 존재하지만 악에 사용될 수 있습니다.
언급URL : https://stackoverflow.com/questions/22898927/injecting-scope-into-an-angular-service-function
'sourcecode' 카테고리의 다른 글
react-select에서 기본값을 설정하는 방법 (0) | 2023.04.04 |
---|---|
angularjs - ng-switch가 ng-model을 바인드하지 않음 (0) | 2023.04.04 |
필드별 MongoDB Aggregate가 존재합니다. (0) | 2023.04.04 |
휴지 상태 개체를 직렬화할 때 이상한 잭슨 예외가 발생함 (0) | 2023.04.04 |
javascript로 URL에 해시태그 첨부 (0) | 2023.04.04 |