2012-09-13 2 views
7

AngularJS에 대한 이해를 돕기 위해 예를 들자면 Todo에 "전체"화면을 추가하기 만하면됩니다. 예를 들어 사용자가 5 가지 방법으로 입력하면 스위치 케이스를 사용하여 다른 div. 코드는 여기에 http://jsfiddle.net/FWCHU/1/ 사용할 수있는 경우 사용할 수 있습니다.AngularJS, 스위치 케이스의 바인드 범위는 무엇입니까?

그러나 각 switch-case는 자체 범위를 가져 오지만 ($ scope.todoText는 사용할 수 없음),이 경우 addTodo() 내에서 "this"를 사용하여 액세스 할 수 있습니다. 지금까지는 좋았지 만 스위치 케이스 외부의 todoText (스위치 케이스 내부에 있음)에 액세스하고 싶다고 말하면 어떻게해야합니까? 스위치 케이스 범위를 모델에 묶을 수 있습니까? 다른 방법으로 액세스 할 수 있습니까? 아니면 다른 방법으로 해결해야합니까?

추신. 나는 이 아니고 위의 코드에 대한 해결책을 찾으려고 노력하고 있습니다. 스위치 케이스를 사용하지 않고 해결하는 방법을 알고있을 것입니다.이 경우 범위가 작동하는 방식을 이해하고 싶습니다!

답변

7

마크는 몇 가지 좋은 제안이있다! AngularJS Batarang Chrome Extension도 확인하여 다양한 범위와 그 값 (다른 것들 중에서도)을 확인하십시오. jsFiddle에서는 잘 작동하지 않는 것으로 나타났습니다.

내부 스코프에 직접 액세스하는 방법을 모르겠지만 여기에는 프리미티브 대신 객체에 바인딩하여 외부 범위의 동일한 텍스트에 액세스하는 한 가지 방법이 있습니다.상기 기존의 기능을 수정)

<form ng-submit="addTodo()"> 
    <input type="text" ng-model="todoText.text" size="30" placeholder="add new todo here"> 
    <input class="btn-primary" type="submit" value="add"> 
</form> 

3 대신 todoTexttodoText.text

$scope.todoText = {text: ''}; 

2) 귀속 :

1) 대신 컨트롤러 프리미티브의 목적으로 todoText 선언 todoText.text :

$scope.addTodo = function() { 
    $scope.todos.push({text:$scope.todoText.text, done:false, width: Math.floor(Math.random() * 100) + 50}); 
    $scope.todoText.text = ''; 
}; 

this fiddle을보고 뭔가를 입력 할 때 입력란 아래에 표시된 텍스트가 바깥 범위의 todoText.text에 액세스합니다.

프리픽스를 사용하도록 코드를 다시 변경하면 (this fiddle에서와 같이) 부모 범위 todoText은 텍스트 상자의 변경 사항을 반영하지 않습니다. 이는 JavaScript가 참조 값을 복사하는 방법 (자세한 내용은 this post 참조)과 AngularJS 관련 사항을 줄이는 방법과 관련이 있습니다.

+0

감사합니다! 그게 바로 내가 뭘 찾고 있었는지 이유는 todoText가 객체로 바인딩 할 때 (todoText.text) 그것이 모든 부모 범위에서 가정하는 기존 객체 속성을 검색한다는 것입니다. "todoText"와는 대조적으로 현재 범위에서 만들어 질 것입니까? – Andreas

+2

AngularJS 코드를 보지 않았지만 새 범위가 만들어지면 값이 자식 범위에 복사됩니다. 프리미티브를 사용하면 값 자체의 사본을 얻는 반면, 객체의 경우 동일한 객체를 가리키는 참조 값을 복사합니다. 프리미티브 (primitive)는 불변 (immutable)하므로, 자식 스코프의 프리미티브가 변경되면 부모의 프리미티브 값에 링크되지 않은 새로운 값이 생성됩니다. 객체의 경우 부모 및 자식 범위의 참조가 동일하므로 속성에 대한 모든 변경 사항이 둘 다에 표시됩니다. 이 바이올린은 내가 설명하려고하는 것을 보여줍니다 : http://jsfiddle.net/uQzyh/ – Gloopy

+0

@Gloopy는 실제로 많은 의미를 갖습니다. – Andreas

5

업데이트 2 : 이제 AngularJS에 대해 조금 더 알고 있습니다. 다음은 훨씬 더 좋은 답변입니다.

스위치 케이스 외부에 외부에있는 (스위치 케이스 내부에있는) todoText에 액세스하고 싶습니다. 어떻게해야합니까?

하위 범위에 액세스 할 수있는 방법이 없습니다. (이 제한, according to Angular developers에 대한 하나의 이유는, 범위의 쉽게 메모리 관리를위한 것입니다.) (글쎄, 당신이 아이의 범위를 액세스 할 $$ childHead 및 $$ childTail을 사용할 수 있지만 당신이해야하지!)

수 나는 switch-case 범위를 모델에 아마도 바인딩합니다. 다른 방법으로는 에 액세스 할 수 있습니까? 아니면 다른 방법으로 해결해야합니까?

  1. 이 @Gloopy이 시사하는 무엇을 : 다음, 부모 범위에서 객체를 생성에 해당 객체에 속성을 참조 자식 범위에서 상위 모델에 액세스하는 세 가지 일반적인 방법이 있습니다

하위 범위.

  • 하위 범위에서 $ parent를 사용하여 부모 범위와 해당 속성 (기본 속성 포함)에 액세스합니다.
  • 전화 부모 범위
  • 의 방법은 $ 부모를 사용하도록 바이올린을 변환하려면

    <input type="text" ng-model="$parent.todoText" ... 
    
    $scope.addTodo = function() { 
        $scope.todos.push({text: $scope.todoText, ... 
        $scope.todoText = ''; 
    

    내가 모두 Gloopy의 대답, NG 반복 및 NG-스위치의 설명에서 언급 한 바와 같이 새로운 자식 범위를 부모 범위에서 프로토 타입 적으로 상속 받도록하십시오. 또한 ng-repeat는 루프 변수/항목을 새 하위 범위에 복사합니다 (@Gloopy가 객체와 기본 요소를 적용하여 설명하는 뉘앙스). ng-switch는 상위 범위에서 아무 것도 복사하지 않습니다.

    는 NG-스위치 후 다음을 추가, 내부/하위 범위의 모양을 확인하려면 :

    <a ng-click="showScope($event)">show scope</a> 
    

    및 컨트롤러에이 추가

    $scope.showScope = function(e) { 
        console.log(angular.element(e.srcElement).scope()); 
    } 
    

    갱신 1 : (잘못된 조언에 취소 선이 추가됨, 명확성을 위해 []이 추가됨)

    AngularJS가 추가 내부 범위를 작성하는이 시나리오의 경우 impl 굳이), 당신은 정말로 다른 컨트롤러를 원하거나 필요로하지 않는다. 나는 Gloopy의 솔루션을 좋아한다. 서비스 (내가 원래 아래에 제안한 것)는 [이 작업을 수행하는 잘못된 방법입니다] 여기에 아마도 잔인한입니다. 나는 또한 Gloopy의 솔루션은 컨트롤러 메소드에서 'this'를 사용할 것을 요구하지 않는다.

    원래 대답 : 범위가 생성되는 곳

    은 (이미이 시도하지 않은 경우, 그것은 편리합니다) 볼 ([]의 명확성을 위해 추가, 나쁜 조언에 추가 취소 선) :

    .ng-scope { margin: 4px; border: 1px dashed red } 
    

    여러 범위가 포함되어 있기 때문에 당신은 본질적으로 간 컨트롤러 통신에 대한 요구하고, (따라서 그 범위 이외의) 스위치의 경우 외부 todoText에 액세스 할 수 있습니다. 몇 가지 옵션이 있지만 서비스가 가장 좋습니다. 서비스 내부에 데이터 (공유해야하는)를 저장하고 데이터에 액세스해야하는 각 컨트롤러에 해당 서비스를 주입하십시오.

    예를 들어 공유 데이터에 액세스하려면 각 스위치 케이스에 컨트롤러를 연결하고 서비스를 주입해야한다고 생각합니다.

    도 참조하십시오. AngularJS: How can I pass variables between controllers?.

    다른 옵션 : 내부 범위에 $ 범위 $ 부모를 사용

    은 [한 가지 방법이 - 볼 갱신 2 위] 하지 않는 것이 좋습니다 다음, 컨트롤러는 방법에 대해 가정을 만드는 것 때문이다. 데이터가 표시됩니다.

    단순한 일회용 응용 프로그램을 제외하고는 $ rootScope를 사용하지 않는 것이 좋습니다. 이 공유 데이터는 자신의 삶을 시작하기 시작할 수 있으며, $ rootScope는 그 일이 일어날 수있는 장소가 아닙니다. 서비스를 재사용하거나 행동을 추가하기가 더 쉽습니다.

    $ scope 사용. $ emit는 또 다른 옵션이지만 지저분하고 약간 이상하게 보입니다. 트리거링 동작 대신 데이터를 공유하는 이벤트가 발생합니다.

    [부모 범위에서 개체를 사용하는 것은 아마 최고 - Gloopy의 답변을 @ 참조하십시오.]

    +0

    나는이 답변도 받아 드리고 싶지만 슬프게도 할 수 없습니다. 나는 실제로 해결책을 제시하기 때문에 다른 하나를 받아들이기로 결정했다. 그러나 귀하의 정보는 순금입니다. 많은 감사드립니다! – Andreas

    관련 문제