Angularjs, 경로 간 범위 전달


87

여러 페이지에 걸쳐 펼쳐지는 양식이있는 상황이 있습니다 (이상적이지 않을 수도 있지만 이것이 방법입니다). 사용자가 단계 사이를 앞뒤로 이동하면 상태를 쉽게 기억할 수 있도록 전체 양식에 대해 하나의 범위를 만들고 싶습니다.

그래서 매우 의사 코드로해야합니다.

  1. 세트 $scope.val = <Some dynamic data>
  2. 링크를 클릭하면 새 템플릿으로 라우팅됩니다 (아마도 동일한 컨트롤러 사용).
  3. $scope.val 마지막 페이지와 동일한 값이어야합니다.

어떻게 든 범위에 대한 데이터를 유지하는 것이 올바른 방법입니까, 아니면 다른 방법이 있습니까? 물론 데이터베이스에 저장하는 것을 제외하고 경로간에 지속되는 범위가있는 컨트롤러를 만들 수도 있습니다.


ganaraj에 추가 된 것처럼 : 여기에 다양한 컨트롤러가 통신하도록하는 방법에 대한 스크린 캐스트가 포함 된 정말 멋진 블로그 항목이 있습니다. 가지고 놀 수있는 몇 가지 유용한 jsfiddles도 있습니다. onehungrymind.com/angularjs-communicating-between-controllers 도움이 되었기를 바랍니다.
F Lekschas

답변:


138

서비스는 앱 수명 내내 지속되므로 서비스를 사용해야합니다.

사용자와 관련된 데이터를 저장하고 싶다고 가정 해 보겠습니다.

다음은 서비스를 정의하는 방법입니다.

app.factory("user",function(){
        return {};
});

첫 번째 컨트롤러에서 :

app.controller( "RegistrationPage1Controller",function($scope,user){
    $scope.user = user;
    // and then set values on the object
    $scope.user.firstname = "John";
    $scope.user.secondname = "Smith";
});

app.controller( "RegistrationSecondPageController",function($scope,user){
        $scope.user = user;
        // and then set values on the object
        $scope.user.address = "1, Mars";

    });

6
아! 나는 전에 그것을 시도했지만 두 경로에 동일한 컨트롤러를 사용했기 때문에 작동하지 못했기 때문에 각 새 경로에서 기본값이 이전 페이지에서 입력 한 값을 덮어 씁니다. 컨트롤러가 두 개이거나 기본값이 없으면 더 이상 발생하지 않습니다. 감사!
Erik Honn

1
무엇에 관한 것입니다 Value Recipe docs.angularjs.org/guide/providers 처럼, myApp.value('clientId', 'a12345654321x');또한 경로 사이의 영구적입니까?
The Bndr

@TheBndr : 그래야합니다. 가치는 내가 이해하는 특별한 형태의 서비스 일뿐입니다.
Robert Koritnik 2014-08-25

3
페이지를 다시로드하면 서비스가 데이터를 유지하지 않습니다 ... 따라서 양식의 4 페이지에서 해당 페이지를 다시로드하면 채워진 모든 데이터가 손실됩니다.
danielrvt

1
좋은 대답입니다! 부수적으로,이 답변을 취하는 사람들을위한 스타일 가이드-생성자가 아닌 서비스 (즉, 새로운 XX로 사용됨)는 소문자 camel로 명명되어야합니다 : github.com/mgechev/angularjs-style-guide .
Matt Byrne 2014 년

9

서비스는 작동하지만 일반 범위와 컨트롤러 만 사용하여이를 수행하는 논리적 방법은 모델의 구조를 반영하도록 컨트롤러와 요소를 설정하는 것입니다. 특히 부모 범위를 설정하는 부모 요소와 컨트롤러가 필요합니다. 양식의 개별 페이지는 상위의 하위보기에 있어야합니다. 상위 범위는 하위보기가 업데이트 되어도 유지됩니다.

중첩 된 명명 된 뷰를 가질 수 있도록 ui-router를 사용하고 있다고 가정합니다 . 그런 다음 의사 코드에서 :

<div ng-controller="WizardController">
  <div name="stepView" ui-view/>
</div>

그런 다음 WizardController는 다중 페이지 양식 ( "마법사"라고 함)의 단계에서 보존하려는 범위 변수를 정의합니다. 그러면 경로 stepView만 업데이트 됩니다. 각 단계에는 자체 템플릿, 컨트롤러 및 범위가있을 수 있지만 해당 범위는 페이지에서 페이지로 손실됩니다. 그러나 WizardController의 범위는 모든 페이지에서 유지됩니다.

자식 컨트롤러에서 WizardController 범위를 업데이트하려면 다음과 같은 구문을 사용 $scope.$parent.myProp = 'value'하거나 setMyProp각 범위 변수에 대해 WizardController 에서 함수 를 정의 해야 합니다. 그렇지 않으면 자식 컨트롤러에서 직접 부모 범위 변수를 설정하려고하면 자식 자체에 새 범위 변수를 만들어 부모 변수를 섀도 잉하게됩니다.

설명하기가 어렵고 완전한 예가 부족한 것에 대해 사과드립니다. 기본적으로 부모 범위를 설정하는 부모 컨트롤러가 필요합니다.이 컨트롤러는 양식의 모든 페이지에서 유지됩니다.


1
이것은 ui-router yes와 함께 작동하지만 (그런 페이지를 디자인하는 꽤 좋은 방법입니다), 즉시 사용할 수는 없습니다. 바로 사용할 수있는 서비스 방법이 바로 그 길입니다.
에릭 Honn

1
명확히하기 위해 부모 범위 속성은 항상 자식 범위에 의해 상속됩니다. 그러나 자식 범위에서 부모 범위 속성을 설정하려면 부모에서 액세스해야합니다. 그렇지 않으면 자식 범위에 동일한 이름의 새 속성을 만듭니다. 부모 범위 속성 설정은 다음과 같이 수행 할 수 있습니다.$scope.$parent.myProp = 'hello world';
mbursill

1
이것은 서비스를 사용하는 것보다 훨씬 더 좋은 접근 방식입니다. 서비스는 싱글 톤이므로 여기에 정의 된 모든 상태는 애플리케이션에 전역입니다. 사용자가 마법사를 도중에 종료 한 다음 다시 시작하면 모든 종료 지점에서 서비스를 올바르게 정리하지 않는 한 이전 실행의 서비스에 남은 상태가있게됩니다. 쉽게 상당한 유지 관리 골칫거리가됩니다!
Dan King

훨씬 더이 답변에 예리한
Kurai Bankusu

Angular UI Router를 사용하지 않는 경우 가장 먼저 떠오르는 것은 서비스입니다. 하지만 UI 라우터를 사용하는 경우 중첩 된 뷰간에 정보를 유지할 수있는 중첩 된 확인이 있습니다. 부모 범위에 액세스하는 것보다 더 깨끗한 접근 방식이 될 것이라고 생각합니다. medium.com/opinionated-angularjs/...
losmescaleros

5

데이터는 두 가지 방법을 통해 컨트롤러간에 전달 될 수 있습니다.

  1. $rootScope
  2. 모델

아래 샘플은 모델을 사용한 값 전달을 보여줍니다.

app.js

angular.module('testApp')
  .controller('Controller', Controller)
  .controller('ControllerTwo', ControllerTwo)
  .factory('SharedService', SharedService);

SharedService.js

function SharedService($rootScope){

 return{
    objA: "value1",
    objB: "value2"
  }
}

// 컨트롤러 A의 값 수정

Controller.js

function Controller($scope, SharedService){

 $scope.SharedService = SharedService;

 $scope.SharedService.objA = "value1 modified";
}

// controllertwo의 값에 액세스

ControllerTwo.js

function ControllerTwo($scope, SharedService){

 $scope.SharedService = SharedService;

 console.log("$scope.SharedService.objA"+$scope.SharedService.objA); // Prints "value1 modified"
}

도움이 되었기를 바랍니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.