수색…


비고

Angular는 범위 트리 를 사용하여 컨트롤러, 지시문 등의 논리를 뷰에 바인딩하고 AngularJS에서 변경 감지의 주요 메커니즘입니다. 범위에 대한 자세한 참조는 docs.angularjs.org 에서 찾을 수 있습니다.

트리의 루트는 injectable 서비스 $ rootScope 를 통해 액세스 할 수 있습니다. 모든 자식 $ 범위는 부모 $ 범위의 메서드와 속성을 상속하므로 어린이는 각도 서비스를 사용하지 않고 메서드에 액세스 할 수 있습니다.

$ scope 상속의 기본 예제

angular.module('app', [])
.controller('myController', ['$scope', function($scope){
    $scope.person = { name: 'John Doe' };
}]);

<div ng-app="app" ng-conroller="myController">
    <input ng-model="person.name" />
    <div ng-repeat="number in [0,1,2,3]">
        {{person.name}} {{number}}
    </div>
</div>

이 예제에서 ng-repeat 지시문은 새로 생성 된 각 자식에 대해 새 범위를 만듭니다.

이러한 생성 된 범위는 부모 범위의 자식이며 (이 경우 myController에서 만든 범위), 따라서 person과 같은 모든 비례를 상속합니다.

프리미티브 값 상속 방지

자바 스크립트에서는, 비 할당 프리미티브 (예 객체, 배열 기능과 같은 값 많은 , 할당 된 값에 대한 참조 (메모리 내의 어드레스)를 유지 이상).

프리미티브 값 (String, Number, Boolean 또는 Symbol)을 두 개의 다른 변수에 할당하고 하나를 변경하면 둘 다 변경되지 않습니다.

var x = 5;
var y = x;
y = 6;
console.log(y === x, x, y); //false, 5, 6

그러나 비 기본 값을 사용하면 두 변수가 동일한 객체에 대한 참조를 유지하기 때문에 하나의 변수 변경하면 다른 변수 변경 됩니다 .

var x = { name : 'John Doe' };
var y = x;
y.name = 'Jhon';
console.log(x.name === y.name, x.name, y.name); //true, John, John

각도에서 범위가 만들어지면 부모의 모든 속성이 할당됩니다. 그러나 이후 속성을 변경하면 기본 범위가 아닌 값인 경우에만 부모 범위에 영향을줍니다.

angular.module('app', [])
.controller('myController', ['$scope', function($scope){
    $scope.person = { name: 'John Doe' }; //non-primitive
    $scope.name = 'Jhon Doe'; //primitive
}])
.controller('myController1', ['$scope', function($scope){}]);

<div ng-app="app" ng-controller="myController">
    binding to input works: {{person.name}}<br/>
    binding to input does not work: {{name}}<br/>
    <div ng-controller="myController1">
        <input ng-model="person.name" />
        <input ng-model="name" />
    </div>
</div>

알아두기 : 각도 스코프는 여러 가지 방법 (예 : 내장 또는 사용자 지정 지시문 또는 $scope.$new() 함수)으로 만들 수 있으며 범위 트리를 추적하는 것은 불가능합니다.

프리미엄이 아닌 값만 범위 속성으로 사용하면 상속하지 않는 속성이나 범위 상속을 인식하는 다른 경우가 아니면 않는 한 안전한쪽으로 계속 이동합니다.

앱 전체에서 사용할 수있는 기능

프로그래머는 기능이 범위 트리에 배치되는 위치와 범위 상속을 모두 기억해야하므로 각도 앱의 디자인이 좋지 않은 것으로 간주 될 수 있습니다. 많은 경우에 서비스를 주입하는 것이 바람직합니다 ( 각도 연습 - 범위 상속과 주입 사용) .

이 예제는 범위 상속이 우리의 요구에 어떻게 사용될 수 있는지, 그리고 전체 앱을 설계하는 모범 사례가 아니라 어떻게 활용할 수 있는지를 보여줍니다.

경우에 따라 범위 상속을 활용하고 함수를 rootScope의 속성으로 설정할 수 있습니다. 이렇게하면 앱의 모든 스코프 (고립 된 스코프 제외)가이 함수를 상속하며 앱의 어느 곳에서나 호출 될 수 있습니다.

angular.module('app', [])
.run(['$rootScope', function($rootScope){
    var messages = []
    $rootScope.addMessage = function(msg){
        messages.push(msg);
    }
}]);

<div ng-app="app">
    <a ng-click="addMessage('hello world!')">it could be accsessed from here</a>
    <div ng-include="inner.html"></div>
</div>

inner.html :

<div>
    <button ng-click="addMessage('page')">and from here to!</button>
</div>

custom $ scope 이벤트 만들기

일반적인 HTML 요소처럼 $ scopes가 자체 이벤트를 가질 수도 있습니다. $ scope 이벤트는 다음과 같은 방법으로 구독 할 수 있습니다 :

 $scope.$on('my-event', function(event, args) {
    console.log(args); // { custom: 'data' }
});

이벤트 수신기의 등록을 취소해야하는 경우 $ on 함수는 바인딩 해제 함수를 반환합니다. 위의 예를 계속하려면 다음을 수행하십시오.

var unregisterMyEvent = $scope.$on('my-event', function(event, args) {
    console.log(args); // { custom: 'data' }
    unregisterMyEvent();
});

사용자 정의 $ scope 이벤트 $ broadcast$ emit 을 트리거하는 두 가지 방법이 있습니다. 특정 이벤트의 범위를 부모에게 알리려면 $ emit을 사용하십시오.

$scope.$emit('my-event', { custom: 'data' }); 

위의 예제는 부모 범위에서 my-event 에 대한 모든 이벤트 리스너를 트리거하고 리스너 my-event 에서 stopPropagation 을 호출하지 않는 한 범위 트리를 $ rootScope 까지 계속합니다. $ emit으로 시작된 이벤트 만 stopPropagation 호출 할 수 있습니다.

$ 방출의 반대 $ 방송이라는 범위의 하위 범위 트리의 모든 자식 범위에있는 모든 이벤트 리스너를 트리거 $ 방송입니다.

$scope.$broadcast('my-event', { custom: 'data' });

$ 브로드 캐스트로 트리거 된 이벤트는 취소 할 수 없습니다.

$ scope 함수 사용하기

$ rootscope에 함수를 선언하는 것이 장점이지만, $ scope 서비스가 삽입 한 코드의 어느 부분이라도 $ scope 함수를 선언 할 수 있습니다. 예를 들어 컨트롤러.

제어 장치

myApp.controller('myController', ['$scope', function($scope){
    $scope.myFunction = function () {
        alert("You are in myFunction!");
    };
}]);

이제 다음을 사용하여 컨트롤러에서 함수를 호출 할 수 있습니다.

$scope.myfunction();

또는 특정 컨트롤러 아래에있는 HTML을 통해 :

<div ng-controller="myController">
    <button ng-click="myFunction()"> Click me! </button>
</div>

지령

각도 지시문 은 범위를 사용할 수있는 또 다른 장소입니다.

myApp.directive('triggerFunction', function() {
    return {
        scope: {
            triggerFunction: '&'
        },
        link: function(scope, element) {
            element.bind('mouseover', function() {
                scope.triggerFunction();
            });
        }
    };
});

동일한 컨트롤러 아래 HTML 코드에서

<div ng-controller="myController">
    <button trigger-function="myFunction()"> Hover over me! </button>
</div>

물론 ngMouseover를 동일한 용도로 사용할 수도 있지만 지시문에서 특별한 점은 원하는 방식으로 사용자 정의 할 수 있다는 것입니다. 그리고 이제 $ scope 함수를 사용하는 방법을 알았습니다.

지침의 범위를 어떻게 제한 할 수 있으며 왜 이것을 할 수 있습니까?

범위는 부모 컨트롤러, 지시문 및 지시문 템플릿 사이에서 통신하는 데 사용되는 "접착제"로 사용됩니다. AngularJS 응용 프로그램이 부트 스트랩 될 때마다 rootScope 객체가 만들어집니다. 컨트롤러, 지시어 및 서비스에 의해 생성 된 각 범위는 rootScope에서 프로토 타입 적으로 상속됩니다.

예, 지침의 범위를 제한 할 수 있습니다. 우리는 지시어를위한 격리 된 범위를 만들어 그렇게 할 수 있습니다.

지시어 범위에는 세 가지 유형이 있습니다.

  1. 범위 : False (지시어는 부모 범위를 사용함)
  2. 범위 : True (지시문이 새로운 범위를 얻음)
  3. 범위 : {} (지시문이 새로운 격리 된 범위를 얻음)

새 격리 된 범위가있는 지시문 : 격리 된 새 범위 를 만들면 부모 범위에서 상속되지 않습니다. 이 새 범위는 부모 범위에서 완전히 분리 되었기 때문에 격리 범위라고합니다. 왜? 격리 된 범위를 사용해야합니다. 사용자 지정 지정 문을 만들려는 경우 분리 된 범위를 사용해야합니다. 이는 우리 지정 문이 일반적이며 응용 프로그램 내부 어디에나 배치되도록하기 때문입니다. 상위 범위는 지시어 범위를 방해하지 않습니다.

격리 된 범위의 예 :

var app = angular.module("test",[]);

app.controller("Ctrl1",function($scope){
    $scope.name = "Prateek";
    $scope.reverseName = function(){
        $scope.name = $scope.name.split('').reverse().join('');
    };
});
app.directive("myDirective", function(){
    return {
        restrict: "EA",
        scope: {},
        template: "<div>Your name is : {{name}}</div>"+
        "Change your name : <input type='text' ng-model='name'/>"
    };
});

AngularJS는 격리 된 범위에 대해 다음과 같은 3 가지 유형의 접두사를 제공합니다.

  1. "@"(텍스트 바인딩 / 단방향 바인딩)
  2. "="(직접 모델 바인딩 / 양방향 바인딩)
  3. "&"(동작 바인딩 / 메서드 바인딩)

이 모든 접두사는 다음과 같이 지시어 요소의 속성에서 데이터를받습니다.

<div my-directive 
  class="directive"
  name="{{name}}" 
  reverse="reverseName()" 
  color="color" >
</div>


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow