programing

Angularjs: '구문으로 컨트롤러' 및 $watch

fastcode 2023. 3. 1. 13:48
반응형

Angularjs: '구문으로 컨트롤러' 및 $watch

사용 시 속성 변경에 가입하는 방법controller as구문?

controller('TestCtrl', function ($scope) {
  this.name = 'Max';
  this.changeName = function () {
    this.name = new Date();
  }
  // not working       
  $scope.$watch("name",function(value){
    console.log(value)
  });
});
<div ng-controller="TestCtrl as test">
  <input type="text" ng-model="test.name" />
  <a ng-click="test.changeName()" href="#">Change Name</a>
</div>  

관련 컨텍스트만 바인딩하면 됩니다.

$scope.$watch(angular.bind(this, function () {
  return this.name;
}), function (newVal) {
  console.log('Name changed to ' + newVal);
});

예: http://jsbin.com/yinadoce/1/edit

갱신:

Bogdan Gersak의 답변은 사실 비슷합니다. 두 답변 모두 구속을 시도합니다.this적절한 문맥을 가지고 있습니다.하지만, 나는 그의 대답이 더 깔끔하다는 것을 알았다.

그렇긴 하지만 무엇보다도 그 이면에 있는 생각을 이해해야 한다.

업데이트 2:

ES6를 사용하시는 분은arrow function올바른 컨텍스트 OOTB를 가진 함수를 얻을 수 있습니다.

$scope.$watch(() => this.name, function (newVal) {
  console.log('Name changed to ' + newVal);
});

저는 보통 이렇게 해요.

controller('TestCtrl', function ($scope) {
    var self = this;

    this.name = 'Max';
    this.changeName = function () {
        this.name = new Date();
   }

   $scope.$watch(function () {
       return self.name;
   },function(value){
        console.log(value)
   });
});

다음을 사용할 수 있습니다.

   $scope.$watch("test.name",function(value){
        console.log(value)
   });

이 예에서는 JSFiddle을 사용하고 있습니다.

TestCtrl의 "test"를 테스트로 사용하는 것과 마찬가지로 다른 답변에서 설명한 바와 같이 스코프를 "self"로 할당할 수 있습니다.

controller('TestCtrl', function($scope){
    var self = this;
    $scope.self = self;

    self.name = 'max';
    self.changeName = function(){
            self.name = new Date();
        }

    $scope.$watch("self.name",function(value){
            console.log(value)
        });
})

이렇게 하면 DOM에서 지정된 이름("TestCtrl as test")에 얽매이지 않고 함수에 .bind(이것을)할 필요도 없습니다.

...지정된 원래 html에서 사용하는 경우:

<div ng-controller="TestCtrl as test">
    <input type="text" ng-model="test.name" />
    <a ng-click="test.changeName()" href="#">Change Name</a>
</div>

AngularJs 1.5는 ControllerAs 구조의 기본 $ctrl을 지원합니다.

$scope.$watch("$ctrl.name", (value) => {
    console.log(value)
});

실제로 함수를 $watch()의 첫 번째 인수로 전달할 수 있습니다.

 app.controller('TestCtrl', function ($scope) {
 this.name = 'Max';

// hmmm, a function
 $scope.$watch(function () {}, function (value){ console.log(value) });
 });

즉, this.name 레퍼런스를 반환할 수 있습니다.

app.controller('TestCtrl', function ($scope) {
    this.name = 'Max';

    // boom
    $scope.$watch(angular.bind(this, function () {
    return this.name; // `this` IS the `this` above!!
    }), function (value) {
      console.log(value);
    });
});

controllerAs에 대한 흥미로운 게시물을 읽어보십시오.https://toddmotto.com/digging-into-angulars-controller-as-syntax/

$onChanges 각도 구성요소 라이프사이클을 사용할 수 있습니다.

https://docs.angularjs.org/guide/component의 컴포넌트 기반 어플리케이션섹션 매뉴얼을 참조해 주세요.

ES6 구문으로 $watch를 쓰는 것은 생각보다 쉽지 않았습니다.할 수 있는 일은 다음과 같습니다.

// Assuming
// controllerAs: "ctrl"
// or
// ng-controller="MyCtrl as ctrl"
export class MyCtrl {
  constructor ($scope) {
    'ngInject';
    this.foo = 10;
    // Option 1
    $scope.$watch('ctrl.foo', this.watchChanges());
    // Option 2
    $scope.$watch(() => this.foo, this.watchChanges());
  }

  watchChanges() {
    return (newValue, oldValue) => {
      console.log('new', newValue);
    }
  }
}

메모: View와 컨트롤러가 경로 또는 지시 정의 개체를 통해 결합되어 있는 경우에는 이 기능이 작동하지 않습니다.아래 그림은 HTML에 "SomeController as SomeCtrl"이 있는 경우에만 작동합니다.Mark V.가 코멘트에서 지적한 것처럼, Bogdan이 하는 것처럼 하는 것이 좋습니다.

사용방법:var vm = this;'이거'라는 단어를 없애기 위해서요그리고나서vm.name = 'Max';그리고 시계 속에서 나는return vm.name@Bogdan이 "self"를 사용하는 것처럼 "vm"을 사용합니다."vm"이든 "self"이든 이 변수는 "this"라는 단어가 함수 내에서 다른 컨텍스트를 차지하기 때문에 필요합니다.(따라서 this.name을 반환할 수 없습니다)그리고 $watch에 도달하려면 아름다운 "컨트롤러 as" 솔루션에 $watch를 삽입해야 합니다.John Papa's Style Guide 참조:https://github.com/johnpapa/angularjs-styleguide#controllers

function SomeController($scope, $log) {
    var vm = this;
    vm.name = 'Max';

    $scope.$watch('vm.name', function(current, original) {
        $log.info('vm.name was %s', original);
        $log.info('vm.name is now %s', current);
    });
}

$scope(및 $watch)를 사용하지 않고 이 작업을 수행하는 방법은 다음과 같습니다.상위 5가지 실수 - 시계 남용

"controller as" 구문을 사용하는 경우 $scope를 사용하지 않는 것이 좋습니다.

이것은 JSFiddle의 코드입니다.(이름을 유지하기 위해 서비스를 사용하고 있습니다.그렇지 않으면 ES5 Object.defineProperty의 set and get 메서드에 의해 무한 호출이 발생합니다.

var app = angular.module('my-module', []);

app.factory('testService', function() {
    var name = 'Max';

    var getName = function() {
        return name;
    }

    var setName = function(val) {
        name = val;
    }

    return {getName:getName, setName:setName};
});

app.controller('TestCtrl', function (testService) {
    var vm = this;

    vm.changeName = function () {
        vm.name = new Date();
    }

    Object.defineProperty(this, "name", {
        enumerable: true,
        configurable: false,
        get: function() {
            return testService.getName();
        },
        set: function (val) {
            testService.setName(val);
            console.log(vm.name);
        }
    }); 
});

언급URL : https://stackoverflow.com/questions/24078535/angularjs-controller-as-syntax-and-watch

반응형