AngularJS 서비스에 현재 범위 전달


106

$scopeAngularJS 서비스에 "현재"를 전달하는 것이 맞 습니까?

나는 $ service가 하나의 컨트롤러에서만 소비된다는 것을 알고 있고 $ service 메서드 자체에서 컨트롤러의 범위에 대한 참조를 갖고 싶습니다.

이것이 철학적으로 옳습니까?

아니면 이벤트를 $ rootScope에 브로드 캐스트 한 다음 컨트롤러가이를 수신하도록하는 것이 더 낫습니까?


1
하려는 작업을보다 구체적으로 알려 주실 수 있습니까? 아마도 서비스에 범위를 적용 할 필요가 전혀 없습니까?
ganaraj

글쎄, 그렇게 어렵지 않습니다. 간단히 말해서, $scope속성 에 액세스하고 $scope.$apply필요할 때 전화를 걸 수 있기를 원합니다 .
SC

또한 $ service의 변경 사항을 $ scope에 적용하고 싶다고 가정 해 보겠습니다. 이제 더 명확 해지기를 바랍니다.
SC

8
서비스가 액세스하기를 원하는 $ scope 속성을 컨트롤러에 넣는 대신 서비스 자체에 넣는 것이 좋습니다. 서비스는 컨트롤러보다 모델 / 데이터를 저장하기에 더 좋은 장소입니다.
Mark Rajcok 2013 년

@MarkRajcock 나는이 문제도 이해하려고 노력하고 있습니다. 현재는 서비스를 호출하고 제공된 데이터를 $scope컨트롤러에 연결하는 중입니다 ... 컨트롤러가 서비스의 데이터에 직접 액세스하고이를 수행하지 않고 뷰에 전달하는 방법은 무엇입니까?
drjimmie1976

답변:


67

비동기가 발생하면 컨트롤러에 알리려면 Angular promise를 사용 하세요.

을 유발하려면 $apply범위가 필요하지 않습니다 $rootScope.$apply. 특정 범위 또는 루트에서 호출하는 데 차이가 없으므로을 호출 할 수 있습니다 .

변수 판독과 관련하여 매개 변수를 받으면 더 좋을 것입니다. 하지만 범위에서 객체 매개 변수로 읽을 수도 있지만 매개 변수를 사용하면 서비스 인터페이스가 훨씬 더 명확 해집니다.


나는 이것이 AngularJS 초보자의 의심을 더 잘 해결하는 대답이라고 생각합니다.
SC

@Caio Cunha 스코프를 통과하는 것이 좋은 생각이 아닌 이유를 확장 해 주시겠습니까? 나는 정확히이 문제가 있는데, $scope비동기 executeSql()함수를 사용하여 서비스 호출을 통해 몇 가지 항목을 추가하고 싶습니다 . 세 가지 옵션을 살펴보면 (1) 비동기 함수에서 콜백을 사용한 다음 호출 $scope.$apply... 이것은 작동하지만 추악합니다 (2) $scope비동기 함수에 전달한 다음 호출 theScope.$apply()... 이것은 또한 작동합니다 (3) 약속을 사용하십시오. .. 아직 시도하지 않았습니다. 약속이 최선의 방법 인 이유는 무엇입니까? 감사!
drjimmie1976 dec.

15

귀하의 기능이 서비스가 필요하지 않은 것보다 하나의 컨트롤러에만 국한되면 말할 것입니다.

컨트롤러 작업은 특정 모델을 조작하는 반면 서비스는 전역 작업을 처리해야합니다. 나는 일을 뒤섞는 것보다이 패러다임을 고수하고 싶다.

이것은 문서가 말하는 것입니다

서비스

Angular 서비스는 웹 앱에 공통적 인 특정 작업을 수행하는 싱글 톤입니다.

제어 장치

Angular에서 컨트롤러는 루트 범위를 제외한 각도 범위의 인스턴스를 늘리는 데 사용되는 JavaScript 함수 (유형 / 클래스)입니다.

추신 : 그 외에도 다이제스트가 필요한 경우 서비스 내에 $ rootScope를 삽입 할 수도 있습니다.


2
감사. 좋은 답변입니다. 내 상황에 깊이 들어가면 싱글 톤을 원하기 때문에 Service를 사용하고 있다는 것입니다. 서비스를 사용하는 컨트롤러는 하나 뿐이지 만이 컨트롤러는 앱 수명주기 동안 여러 번 인스턴스화 될 수 있으므로 서비스가 항상 동일한 상태에 있기를 원합니다.
SC

어쨌든 전화 $apply또는 $digest$ rootScope 에 대한 설명은 나 에게 완전히 의미가 있습니다.
SC

1
나는 여전히 테스트를 위해 서비스로 별도로 보관할 것입니다.
bluehallu 2014

기능이 컨트롤러의 한 인스턴스 에만 국한된 경우 서비스 구현을 건너 뛸 수 있지만 그렇지 않으면 해당 인스턴스간에 상태를 공유하는 기능을 희생 할 수 없습니다. 또한 오늘날 단일 유형의 컨트롤러가 있다고해서 내일 기능을 활용할 수있는 다른 컨트롤러가 없다는 의미는 아닙니다. 또한 서비스는 컨트롤러의 팽창을 방지 할 수 있습니다. 따라서 단일 컨트롤러가 있는지 여부에 대한 질문이 아니라 문제가되는 기능이 무엇인지에 대한 질문입니다.
Nick

9

예. 초기화 할 때 $ scope를 서비스에 전달할 수 있습니다. 서비스 생성자에서 this._scope와 같은 것에 범위를 할당 한 다음 서비스 내에서 범위를 참조 할 수 있습니다!

angular.module('blah').controller('BlahCtrl', function($scope, BlahService) {

    $scope.someVar = 4;

    $scope.blahService = new blahService($scope);

});

angular.module('blah').factory('blahService', function() {

    //constructor
    function blahService(scope) {
        this._scope = scope;

        this._someFunction()
    }

    //wherever you'd reference the scope
    blahService.prototype._someFunction = function() {

        this._scope['someVar'] = 5;

    }

    return blahService;

});

1
그러나 나는 $scope주어진 컨트롤러가 서비스를 주입 할 때마다 각 컨트롤러를 자동으로 알 수있는 방법을보고 싶습니다 . 서비스에 대한 메서드를 호출하고 수동으로 전달할 필요 $scope가 없습니다.
Cody

2
@Cody 나는 의존성 주입과 모순되기 때문에 권장하지 않습니다
Coldstar

동의합니다. 저를 쏘아서 +1했습니다! 아마도 정육점 DIP도-중복 될 위험이 있습니다.
Cody

여기서 공장과 서비스를 혼합하고 있습니다. 이 솔루션은 서비스와 다른 공장을 사용합니다. 주요 차이점은 서비스가 (싱글 톤) 객체를 반환한다는 것입니다. 팩토리는 인스턴스화 할 수있는 함수를 반환하는 반면 ( new MyFunction()). 질문은 부름 new이 옵션이 아닌 서비스에 관한 것이 었습니다.
Karvapallo 2015-08-23

@Karvapallo 좋은 지적입니다. 카운터 포인트로 각도 서비스가 공장, 서비스 및 공급자 (ng-wat)를 지칭한다고 생각합니까?
user12121234

6

개인적 $scope으로 서비스에 전달 하는 것은 일종의 순환 참조를 생성하기 때문에 나쁜 생각 이라고 생각 합니다. 컨트롤러는 서비스에 의존하고 서비스는 컨트롤러의 범위에 의존합니다.

관계 측면에서 혼란 스러울뿐만 아니라 이와 같은 것들이 가비지 수집기를 방해하게됩니다.

내가 선호하는 접근 방식은 도메인 개체 를 컨트롤러 범위에 넣고이를 서비스에 전달하는 것입니다. 이렇게하면 서비스가 컨트롤러 내부에서 사용되는지 아니면 향후 다른 서비스 내부에서 사용되는지에 관계없이 작동합니다.

예를 들어 서비스가 array에서 요소를 푸시하고 팝해야하는 경우 errors내 코드는 다음과 같습니다.

var errors = [];
$scope.errors = errors;
$scope.myService = new MyService(errors);

그러면 서비스는에서 작동하여 컨트롤러와 상호 작용합니다 errors. 물론 전체 배열 참조를 지우지 않는 것에 대해주의해야하지만 결국에는 일반적인 JS 문제입니다.

나는 방송 $apply이나 그와 비슷한 것을 사용하고 싶지 않다 . 왜냐하면 imho의 좋은 OO-practics는 Angular-magics를 항상 능가 할 것이기 때문이다.


1
이 코드는 이것과 어떤 차이가 있습니까? :$scope.errors = []; $scope.myService = new MyService($scope.errors);
Soldeplata Saketos

@SoldeplataSaketos-예, 그렇습니다. errors독립적으로 살고있다 $scope. 이것이이 답변의 요점입니다. Pls는 내가 텍스트에서 제공 한 링크를 확인합니다. 건배.
Marco Faustinelli

1
코드를 올바르게 이해하고을 $scope.errors가리키고 var errors변수 오류가 다른 포인터이므로 나에게 중복되어 보입니다. 내가 생각할 수있는 비슷한 상황 중 하나이며 뻔뻔스럽게 중복되는 코드는 const errors = errors2 = errors3 = []; $scope.errors = errors;. 제공 한 코드 만 var errors = []중복 되는 것 같다는 데 동의하십니까 ?
Soldeplata Saketos

아니, 그렇지 않습니다. 나는 단어 나 자신에게 말을 반복 : errors독립적으로 살고있다 $scope. 도메인 개체가 무엇이며 var할당이 무엇인지 이해해야합니다 . 내가 제공 한 링크가 충분하지 않으면 다른 자료를 많이 사용할 수 있습니다.
Marco Faustinelli

음, 그것은 전적으로 함수의 구현에 달려 있습니다 MyService(errors). 내 이해에 따르면 서비스는 매개 변수 (이 경우 포인터)를 기반으로 로깅 배열을 생성해야합니다. 서비스가 각도의 단일 항목이기 때문에 나에게 그것은 나쁜 패턴입니다. 서비스 구현이 잘 프로그래밍 된 경우 내부 변수에 배열을 생성해야합니다 (싱글 톤을 유지하기 위해). 따라서 서비스 외부에서 변수를 초기화하는 것은 의미가 없습니다.
Soldeplata Saketos
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.