AngularJs "controller as"구문-설명?


121

나는 angularJS 의 새로운 구문에 대해 읽었습니다.controller as xxx

구문 InvoiceController as invoice은 Angular에게 컨트롤러를 인스턴스화하고 현재 범위의 변수 송장에 저장하도록 지시 합니다 .

시각화 :

여기에 이미지 설명 입력

좋아, 그래서 나는 $scope내 컨트롤러에 매개 변수 가 없으며 코드는 컨트롤러에서 훨씬 더 깨끗해질 것입니다.

그러나

뷰에서 다른 별칭을 지정해야 합니다.

그래서 지금까지 할 수있었습니다.

<input type="number" ng-model="qty"  />

....controller('InvoiceController', function($scope) {
   // do something with $scope.qty <--notice

이제 할 수 있습니다.

 <input type="number" ng-model="invoic.qty"  /> <-- notice 

  ....controller('InvoiceController', function() {
       // do something with  this.qty  <--notice

질문

그것을하는 목표는 무엇입니까? 한 장소에서 삭제하고 다른 장소에 추가 하시겠습니까?

내가 무엇을 놓치고 있는지 보게되어 기쁠 것입니다.


8
이 비디오는 그것을 아주 잘 설명합니다. youtube.com/watch?v=tTihyXaz4Bo HTML에서 더 깨끗한 코드에 사용되는 것 같습니다.
Fizer Khan

1
명쾌함. 컨트롤러에서 $ scope.x Vs this.x를 사용하는 것에 대해 신경 쓰지 않지만 {{invoice.x}}에 대한 바인딩은 {{x}} (imho) 이상을 알려줍니다. 또한 이것이 컨트롤러의 비 객체에 문제가있는 각도에서 들었던 문제를 해결하는지 궁금합니다 (예 : things.x는 괜찮지 만 x가 문제를 일으킬 수 있음).
Matt Roberts

1
@MattRoberts는 귀하의 마지막 의견을 해결하기 위해-귀하가 참조하는 비 객체 문제는 자바 스크립트 프로토 타입 상속의 사실만큼 각도 문제가 아닙니다. 여기 에 각도 에서 발생하는 이유에 대한 좋은 설명이 있습니다 (왜 controller as수정 되었는지 포함).
Russ Matney

$ scope. $ broadcast를 어떻게 대체합니까? .이 새로운 경우 내이 $ 방송은 작동하는 것 같군하지 않기 때문에
Gaurav

1
@Gaurav는 컨트롤러를 일부 속성, 메서드 등의 구문으로 사용하더라도 $ scope 서비스를 컨트롤러에 삽입 할 수 있습니다.
Derek

답변:


163

그것에 대해 몇 가지가 있습니다.

어떤 사람들은 $scope구문을 좋아하지 않습니다 (이유는 묻지 마십시오). 그들은 그냥 사용할 수 있다고 말합니다 this. 그것이 목표 중 하나였습니다.

속성의 출처를 명확히하는 것도 정말 유용합니다.

컨트롤러를 중첩 할 수 있으며 html을 읽을 때 모든 속성이 어디에서 오는지 매우 명확합니다.

또한 일부 점 규칙 문제를 피할 수 있습니다 .

예를 들어 두 개의 컨트롤러가 모두 동일한 이름 인 'name'인 경우 다음을 수행 할 수 있습니다.

<body ng-controller="ParentCtrl">
    <input ng-model="name" /> {{name}}

    <div ng-controller="ChildCtrl">
        <input ng-model="name" /> {{name}} - {{$parent.name}}
    </div>
</body>

부모와 자식을 모두 수정할 수 있습니다. 문제는 없습니다. 하지만 당신은 사용해야합니다$parent 부모의 이름을 보려면 합니다. 자식 컨트롤러에 숨 겼기 때문입니다. 거대한 HTML 코드에서는 $parent문제가 될 수 있으며 그 이름의 출처를 알지 못합니다.

로에게 controller as당신이 할 수 있습니다 :

<body ng-controller="ParentCtrl as parent">
    <input ng-model="parent.name" /> {{parent.name}}

    <div ng-controller="ChildCtrl as child">
      <input ng-model="child.name" /> {{child.name}} - {{parent.name}}
    </div>
</body>

같은 예이지만 읽기가 훨씬 더 명확합니다.


10
또한 여기에이 방법이 일부 혼동 될 이유의 아주 좋은 예입니다 stackoverflow.com/questions/25405543/...은
줄리안 HOLLMANN

이것은 컨트롤러를 중첩 할 때 매우 유용합니다!
C_J

1
나는 당신의 대답 비슷한 구현에 문제가있어, 참조하시기 바랍니다 stackoverflow.com/questions/38315538
코디

또한 es6 클래스를 컨트롤러로 사용하고 HTML의 메서드를 참조 할 수 있습니다. foo() { ... }보다 깨끗합니다 $scope.foo = function() { ... }.
브라이언 McCutchon

17

controller as내가 본 구문 의 주요 이점 은 $ scope 장식 함수뿐만 아니라 컨트롤러를 클래스로 사용하여 상속을 활용할 수 있다는 것입니다. 여러 컨트롤러와 매우 유사한 기능이있는 상황이 자주 발생하며 가장 확실한 방법은 BaseController클래스 를 만들고 상속하는 것입니다.

이 문제를 부분적으로 해결하는 $ scope 상속이 있지만 일부 사람들은 더 많은 OOP 방식으로 코드를 작성하는 것을 선호합니다. 제 생각에는 코드를 추론하고 테스트하기가 더 쉽습니다.

다음은 시연 할 바이올린입니다. http://jsfiddle.net/HB7LU/5796/


1
Fiddle이 정말 도움이 되었기 때문에 이것은 더 많은 upvotes를 얻을 것입니다
Mawg는 Monica를

13

중첩 된 범위가있을 때 한 가지 특별한 이점이 분명하다고 생각합니다. 이제 속성 참조의 범위가 정확히 무엇인지 완전히 명확 해집니다.


7

출처

구문 및 VM을 $scope object사용하여 컨트롤러를 만드는 것과 “controller as”구문 및 VM을 사용하는 것의 차이점

$ scope 개체를 사용하여 컨트롤러 만들기

일반적으로 아래 목록에 표시된대로 $ scope 개체를 사용하여 컨트롤러를 만듭니다.

myApp.controller("AddController", function ($scope) {



    $scope.number1;

    $scope.number2;

    $scope.result;

    $scope.add = function () {

        $scope.result = $scope.number1 + $scope.number2;

    }

});

위에서 우리는 서로 통신하는 $ scope 객체 컨트롤러와 뷰를 사용하여 세 개의 변수와 하나의 동작으로 AddController를 생성하고 있습니다. $ scope 개체는 데이터와 동작을 뷰에 전달하는 데 사용됩니다. 뷰와 컨트롤러를 함께 붙입니다.

기본적으로 $ scope 개체는 다음 작업을 수행합니다.

  1. 컨트롤러에서 뷰로 데이터 전달

  2. 컨트롤러에서 뷰로 동작 전달

  3. 컨트롤러를 붙이고 함께보기

  4. $ scope 개체는보기가 변경되면 수정되고 $ scope 개체의 속성이 변경되면보기가 수정됩니다.

$ scope 개체에 속성을 연결하여 데이터와 동작을 뷰에 전달합니다. 컨트롤러에서 $ scope 개체를 사용하기 전에 컨트롤러 함수에 종속성으로 전달해야합니다.

"controller as"구문 및 vm 사용

아래 목록과 같이 컨트롤러를 구문으로 사용하고 vm 변수를 사용하여 위의 컨트롤러를 다시 작성할 수 있습니다.

myApp.controller("AddVMController", function () {

    var vm = this;

    vm.number1 = undefined;

    vm.number2=undefined;

    vm.result =undefined;

    vm.add = function () {

        vm.result = vm.number1 + vm.number2;

    }

});

본질적으로 우리는 이것을 변수 vm에 할당하고 속성과 동작을 거기에 연결합니다. 뷰에서 컨트롤러를 구문으로 사용하여 AddVmController에 액세스 할 수 있습니다. 이것은 아래 목록에 나와 있습니다.

<div ng-controller="AddVMController as vm">

            <input ng-model="vm.number1" type="number" />

            <input ng-model="vm.number2" type="number" />

            <button class="btn btn-default" ng-click="vm.add()">Add</button>

            <h3>{{vm.result}}</h3>

  </div>

물론 컨트롤러에서 "vm"이 아닌 다른 이름을 구문으로 사용할 수 있습니다. 내부적으로 AngularJS는 $ scope 객체를 만들고 속성과 동작을 연결합니다. 그러나 컨트롤러를 구문으로 사용하면 코드가 컨트롤러에서 매우 깨끗하고 별칭 이름 만 뷰에 표시됩니다.

컨트롤러를 구문으로 사용하는 몇 가지 단계는 다음과 같습니다.

  1. $ scope 개체없이 컨트롤러를 만듭니다.

  2. 이것을 지역 변수에 할당하십시오. 나는 vm으로 변수 이름을 선호했으며 원하는 이름을 선택할 수 있습니다.

  3. vm 변수에 데이터와 동작을 연결합니다.

  4. 보기에서 컨트롤러를 구문으로 사용하여 컨트롤러에 별칭을 제공합니다.

  5. 별칭에 모든 이름을 지정할 수 있습니다. 중첩 컨트롤러로 작업하지 않는 한 vm을 사용하는 것을 선호합니다.

컨트롤러를 만들 때 $ scope 개체 접근 방식이나 컨트롤러를 구문으로 사용하는 직접적인 장점이나 단점은 없습니다. 순전히 선택의 문제이지만 컨트롤러를 구문으로 사용하면 컨트롤러의 JavaScript 코드를 더 쉽게 읽을 수 있고이 컨텍스트와 관련된 문제를 방지 할 수 있습니다.

$ scope 개체 접근 방식의 중첩 컨트롤러

아래 목록에 표시된대로 두 개의 컨트롤러가 있습니다.

myApp.controller("ParentController", function ($scope) {



    $scope.name = "DJ";

    $scope.age = 32;

});

myApp.controller("ChildController", function ($scope) {



    $scope.age = 22;

    $scope.country = "India";



});

속성 "age"는 두 컨트롤러 모두 내부에 있으며보기에서이 두 컨트롤러는 아래 목록과 같이 중첩 될 수 있습니다.

<div ng-controller="ParentController">



            <h2>Name :{{name}} </h2>

            <h3>Age:{{age}}</h3>



             <div ng-controller="ChildController">

                    <h2>Parent Name :{{name}} </h2>

                    <h3>Parent Age:{{$parent.age}}</h3>

                    <h3>Child Age:{{age}}</h3>

                    <h3>Country:{{country}}</h3>

             </div>

        </div>

보시다시피 부모 컨트롤러의 age 속성에 액세스하려면 $ parent.age를 사용하고 있습니다. 여기서 문맥 분리는 명확하지 않습니다. 그러나 컨트롤러를 구문으로 사용하면 중첩 된 컨트롤러로보다 우아한 방식으로 작업 할 수 있습니다. 아래 목록에 표시된대로 컨트롤러가 있다고 가정 해 보겠습니다.

myApp.controller("ParentVMController", function () {

    var vm = this;

    vm.name = "DJ";

    vm.age = 32;

});

myApp.controller("ChildVMController", function () {

    var vm = this;

    vm.age = 22;

    vm.country = "India";



});

보기에서이 두 컨트롤러는 아래 목록과 같이 중첩 될 수 있습니다.

<div ng-controller="ParentVMController as parent">



            <h2>Name :{{parent.name}} </h2>

            <h3>Age:{{parent.age}}</h3>



            <div ng-controller="ChildVMController as child">

                <h2>Parent Name :{{parent.name}} </h2>

                <h3>Parent Age:{{parent.age}}</h3>

                <h3>Child Age:{{child.age}}</h3>

                <h3>Country:{{child.country}}</h3>

            </div>

 </div>

컨트롤러로서의 구문에는 더 읽기 쉬운 코드가 있으며 부모 속성은 $ parent 구문을 사용하는 대신 부모 컨트롤러의 별칭 이름을 사용하여 액세스 할 수 있습니다.

컨트롤러를 구문으로 사용할 것인지 $ scope 객체로 사용할 것인지는 순전히 귀하의 선택이라고 말하면서이 게시물을 마무리하겠습니다. 뷰에 중첩 된 컨트롤러가 명확하게 구분되어 있으므로 컨텍스트에서 제어 할 수있는 구문으로서의 컨트롤러가 작업하기가 조금 더 쉽다는 점에서 두 가지 모두에 큰 장점이나 단점이 없습니다.


4

메서드 / 속성이 범위 개체가 아닌 컨트롤러 인스턴스와 직접 연결되어 있기 때문에 주요 이점은보다 직관적 인 API입니다. 기본적으로 이전 접근 방식에서는 컨트롤러가 스코프 객체를 구축하기위한 장식이됩니다.

이에 대한 추가 정보는 다음과 같습니다. http://www.syntaxsuccess.com/viewarticle/551798f20c5f3f3c0ffcc9ff


3

내가 읽은 것에서 $ scope는 Angular 2.0에서 제거되거나 적어도 $ scope 사용을 보는 방식에서 제거됩니다. 2.0 릴리스가 가까워지면 컨트롤러 사용을 시작하는 것이 좋습니다.

그것에 대한 더 많은 논의를 위해 여기 비디오 링크 .

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