ProgramingTip

내 구성 요소 바인딩이에서 정의되지 않은 이유는 무엇입니까?

bestdevel 2020. 12. 8. 19:20
반응형

내 구성 요소 바인딩이에서 정의되지 않은 이유는 무엇입니까?


저는 간단한 각도 구성 요소를 작성하고 있습니다. 매개 변수를 바인딩으로 전달하고 그 값을 화면에 표시합니다. 모두 잘 작동합니다. 화면에 매개 변수가 표시되는 것을 볼 수 있습니다.

구성 요소 :

var app = angular.module("test", []);
app.component("test", {
  bindings: {
    "contactId": "<"
  },
  controllerAs: "model",
  controller: () => {
    //output: 'contact id from controller: undefined'
    console.log(`contact id from controller: ${this.contactId}`);
  },
  template: "<div>Contact id from view: {{model.contactId}}</div>"
});

HTML :

<test contact-id="8"></test>

그러나 컨트롤러 내에서 바인딩에 액세스하려고 (console.log 참조) 바인딩 값은 undefined. 보기에서 어떻게 사용할 수 있는지 이해하지 못하지만, 사용할 수 없습니다.

내가 도대체 ​​뭘 잘못하고있는 겁니까?

다음 은 문제를 설명 하는 plnkr 입니다.


앵귤러의 구성 요소를 사용할 때 컨트롤러가 내부 연결을 통해 연결되지 않은 지점이 있습니다. 컨트롤러의 생성자 에서이 작업을 수행하려는 경우 바인딩 연결 되지 않은 것 입니다. Component API는 특정 시간에 실행되는 정의 할 수있는 몇 가지 수명주기 후크를 노출합니다. 당신은 $onInit후크를 찾고 있습니다.

$ onInit ()-요소의 모든 컨트롤러가 구성되고 바인딩이 초기화 된 후 (이 요소의 지시문에 대한 사전 및 사후 연결 함수 이전에) 각 컨트롤러에서 호출됩니다. 컨트롤러에 대한 초기화 코드를 넣을 수있는 좋은 장소입니다.

문서 당 -https : //docs.angularjs.org/guide/component


HTML의 바인딩에는 하이픈사용 하고 Javascript의 바인딩에는 camelCase를 사용 합니다.

app.component("test", {
  bindings: {
    "myContactId": "<"
  }
}

<test my-contact-id="8"></test>

그게 제가 항상 잊는 일입니다.


의 값 contactId은은 $scope컨트롤러에서 사용할 수 있습니다 .

var app = angular.module("test", []);
app.component("test", {
  bindings: {
    "contactId": "<"
  },
  controllerAs: "model",
  controller: ($scope) => {
    var model = $scope.model;
    alert(`contact id from controller: ${model.contactId}`);
  },
  template: "<div>Contact id from view: {{model.contactId}}</div>"
});

여기 에서 다른 버전의 Plunker에 연결 합니다 .


키워드 this 가 화살표 기능과 함께 작동하지 않는 것입니다.

controller: function() {
   alert('contact id from controller: ' + this.contactId);
}

화살표 기능을 사용할 때이 도구 는 창 개체를 참조하는 것입니다.

효율적으로 사용하고 있습니다.


이 비정상적인 버그를 피하기 위해 필요한 몇 가지 변경 사항을 제안 할 것입니다.

app.component("test", {
  bindings: {
    "myContactId": "<"
  },
  controller:function(){
   var self=this;
   this.$onInit=function(){
    // do all your initializations here.
    // create a local scope object for this component only. always update that scope with bindings. and use that in views also.

       self.myScopeObject=self.myContactId
   }
  },
   template:'<p>{{$ctrl.myScopeObject}}</p>'
 }

<test my-contact-id="8"></test>

몇 가지 포인트 :

  1. html의 구성 요소에 바인딩을 전달하는 것은 항상 my-contact-id와 같은 케밥 케이스가되며 해당 javascript 변수는 cammal 케이스 인 myContactId가됩니다.

  2. 개체의 값을 전달하는 경우 바인딩에서 '@'를 사용하십시오. 객체를 사용하고 객체를 bindigs에 전달하는 경우 '<를 사용하십시오. 해당 객체에 양방향 바인딩을 원하면 바인딩 구성에서 '='를 사용하십시오.

 bindings:{
      value:'@',
      object:'<', // also known as one-way
      twoWay:'='
    }

모범 사례는 아니지만 해당 값에 더 쉽게 액세스 할 수 있습니다.

$scope.$ctrl.contactId

$ scope 내의 $ ctrl 속성에서 모든 바인딩을 가져올 수 있습니다.

나는 그것의 도움을 바랍니다


구성 요소가 가정되는 지시문을 사용하는 경우 bindings {}가 지정되면 동일한 매개 변수를 scope {}에 추가하는 것으로 나타납니다.

/*bindings: {
    modalInstance: '<',
    resolve: '<'
},*/
scope: {
    modalInstance: '<',
    resolve: '<'
},

* 위에서 추가 범위 매개 변수 인 foo를 $ scope.resolve에서 할당 할 때까지 $ scope에서 사용할 수 없다는 사실을 발견했습니다. 그래서 $ scope.init ()에서 이것을해야했습니다 : $ scope.foo = $ scope.resolve.foo. 이유가 확실하지 않습니다. 내 UI Bootstrap Modal + Directives 사용과 관련이 있다고 생각합니다.

이것은 다른 사람들에게는 분명 할 수 있지만 AnguluarJS에 상대적으로 새로운 것은 아닙니다.

내 문제는 Directives와 호환되지만 구성 요소와 함께 사용하도록 설계되고 문서화 된 UI-Bootstrap 모달과 함께 Directives를 사용하는 것이 었습니다.


내 문제가 발생할 수있는 사람들을 위해 @jusopi 및 허용 된 답변에 대한 후속 답변으로 또 다른 답변을 추가 할 것입니다. 구성 요소와 관련하여 $onInit후크 후에도 서버의 값이 여전히 수신되지 않았기 때문에 내 데이터는 여전히 null이었습니다. 이에 대응하기 위해 (이 상황을 처리하는 더 좋은 방법이있을 수 있지만) $onChanges후크 도 활용했습니다 . $onChanges전달 될 때 변경된 데이터를 반환하고 해당 정보를 구문 분석하거나 간단히 바인딩을 호출하면 this.contactId업데이트됩니다.

자세한 내용은 https://docs.angularjs.org/guide/component 문서 에서 제공됩니다 .


"정의되지 않은"오류를 일으키는 코드에는 두 가지 문제가 있습니다.

  1. 위에서 언급했듯이 $ onInit 수명주기 후크에 먼저 도달해야하며 모든 바인딩이 완료되면 onInit가 실행됩니다.

공식 문서에서 : AngularJs 문서

$ onInit ()-요소의 모든 컨트롤러가 구성되고 바인딩이 초기화 된 후 (이 요소의 지시문에 대한 사전 및 사후 연결 함수 이전에) 각 컨트롤러에서 호출됩니다. 컨트롤러에 대한 초기화 코드를 넣을 수있는 좋은 장소입니다.

  1. 두 번째 문제는 컨트롤러 함수의 매개 변수로 "() =>"화살표 표기법을 사용할 때 컨트롤러가 라이프 사이클 훅에 도달하지 못한다는 것입니다.

문제는 화살표 표기법이 자체 범위가 아니라 둘러싸는 범위를 사용한다는 것입니다. "this"를 사용할 때 구성 요소가 아닌 창 개체를 참조한다는 의미입니다. 따라서 this. $ onInit () 호출은 창에서 호출되고 창에 존재하지 않기 때문에 실행되지 않습니다.

참고 URL : https://stackoverflow.com/questions/38591685/why-are-my-component-bindings-undefined-in-its-controller

반응형