programing

부모에서 자식으로 각진 상태로 이벤트 전달JS 구성요소

css3 2023. 11. 1. 22:32

부모에서 자식으로 각진 상태로 이벤트 전달JS 구성요소

제가 하고 있는 새로운 프로젝트에서는 지시사항 대신에 구성요소를 사용하기 시작했습니다.

하지만 구체적인 방법을 찾을 수 없는 문제에 봉착했습니다.

이벤트를 자녀에서 부모로 쉽게 알릴 수 있습니다. 아래의 제 플렁커에서 찾을 수 있습니다. 하지만 부모에서 자녀로 이벤트를 알리는 올바른 방법은 무엇입니까?

Angular2는 다음과 같은 것을 사용하여 이 문제를 해결하는 것처럼 보입니다. https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#parent-to-child-local-var 하지만 예제가 #timer에서 했던 것처럼 자식 구성 요소에 "pointer"을 정의할 가능성은 없다고 생각합니다.

Angular2로 쉽게 변환할 수 있도록 하기 위해 다음을 피하고 싶습니다.

  • 이벤트 방출(스코프에서 emit 및 브로드캐스트)
  • 자식의 요구사항을 사용합니다(그리고 부모에게 콜백을 추가합니다..UGLY).
  • 단방향 바인딩을 사용하여 아이에게 스코프를 주입한 다음 이 속성을 "감시"합니다.더 못생김

예제 코드:

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

app.controller('RootController', function() {
});

app.component('parentComponent', {
  template: `
    <h3>Parent component</h3>
    <a class="btn btn-default btn-sm" ng-click="$ctrl.click()">Notify Child</a>
    <span data-ng-bind="$ctrl.childMessage"></span>
    <child-component on-change="$ctrl.notifiedFromChild(count)"></child-component>
  `,
  controller: function() {
    var ctrl = this;
    ctrl.notifiedFromChild = function(count){
      ctrl.childMessage = "From child " + count;
    }
    ctrl.click = function(){
    }
  },
  bindings: {
  }
});

app.component('childComponent', {
  template: `
    <h4>Child component</h4>
    <a class="btn btn-default btn-sm" ng-click="$ctrl.click()">Notify Parent</a>
  `,
  controller: function() {
    var ctrl = this;
    ctrl.counter = 0;
    ctrl.click = function(){
        ctrl.onChange({ count: ++ctrl.counter });
    }
  },
  bindings: {
    onChange: '&'
  }
});

여기서 예를 찾을 수 있습니다.

http://plnkr.co/edit/SCK8XlYoYCRceCP7q2Rn?p=preview

이것은 내가 만든 가능한 해결책입니다.

http://plnkr.co/edit/OfANmt4zLyPG2SZyVNLr?p=preview

아이가 부모를 필요로 하는 경우, 그리고 아이가 아이에 대한 부모 참조를 설정하는 경우...이제 부모가 아이를 이용할 수 있습니다...못생겼지만 위의 각2 예와 같습니다.

부모에서 자식으로 각진 상태로 이벤트 전달JS 구성요소

식 바인딩을 사용하여 지시 $API 게시

상위 구성 요소가 이벤트를 하위 구성 요소와 통신할 수 있도록 하려면 하위 구성 요소가 API를 게시하도록 합니다.

<grid-component grid-on-init="$ctrl.gridApi=$API; $ctrl.someFn($API)">
</grid-component>    

JS

app.component('gridComponent', {
  //Create API binding
  bindings: {gridOnInit: "&"},
  template: `
    <h4>Grid component</h4>
    <p> Save count = {{$ctrl.count}}</p>
  `,
  controller: function() {
    var ctrl = this;
    this.$onInit = function() {
        ctrl.count = 0;
        ctrl.api = {};
        //Publish save function
        ctrl.api.save = save;
        //Invoke Expression with $API as local
        ctrl.gridOnInit({$API: ctrl.api});
    };
    function save(){
      console.log("saved!");
      ctrl.count++;
    }
  }
});

위의 예는 에 의해 정의된 Angular Expression을 호출합니다.grid-on-initAPI가 노출된 속성을 다음과 같습니다.$API. 이 접근 방식의 장점은 부모가 각도식을 사용하여 자식 구성 요소에 함수를 전달하여 자식 초기화에 반응할 수 있다는 것입니다.

문서에서:

'isolate' 스코프 개체 해시는 지시 요소의 속성에서 파생된 로컬 스코프 속성 집합을 정의합니다.이러한 로컬 속성은 템플릿의 별칭 값에 유용합니다.개체 해시의 키는 분리 범위의 속성 이름에 매핑됩니다. 값은 지시 요소에 대한 일치 속성을 통해 속성이 상위 범위에 바인딩되는 방법을 정의합니다.

  • &아니면&attr- 는 상위 범위의 컨텍스트에서 식을 실행하는 방법을 제공합니다.특성 이름을 지정하지 않으면 특성 이름이 로컬 이름과 동일한 것으로 가정됩니다.정해진<my-component my-attr="count = count + value">격리 범위 정의 범위:{ localFn:'&myAttr' }, 격리 범위 속성localFn기능 래퍼를 가리킬 것입니다.count = count + value expression. 종종 식을 통해 격리된 범위에서 상위 범위로 데이터를 전달하는 것이 바람직합니다.이것은 로컬 변수 이름과 값의 맵을 식 래퍼 fn에 전달함으로써 수행할 수 있습니다.예를 들어 식이 다음과 같다면increment($amount)그러면 우리는 전화를 함으로써 금액 값을 지정할 수 있습니다.localFn~하듯이localFn({$amount: 22}).

-- 각진JS 포괄지침 API -- 범위

관례적으로 지역 변수의 접두사는 다음과 같이 지정할 것을 권장합니다.$부모 변수와 구별할 수 있습니다.


양방향 바인딩 대신 사용

참고: 각도 2+로 쉽게 전환하려면 양방향을 사용하지 마십시오.=구속력이 있는단방향 사용 대신<구속력과 표현력&구속력이 있는자세한 내용은 각도를 참조하십시오.JS 개발자 가이드 - 구성 요소 이해

상위 구성 요소가 이벤트를 하위 구성 요소와 통신할 수 있도록 하려면 하위 구성 요소가 API를 게시하도록 합니다.

<grid-component api="$ctrl.gridApi"></grid-component>

위의 예에서,grid-component바인딩을 사용하여 API를 상위 범위에 게시합니다.api기여하다.

app.component('gridComponent', {
  //Create API binding
  bindings: {api: "="},
  template: `
    <h4>Grid component</h4>
    <p> Save count = {{$ctrl.count}}</p>
  `,
  controller: function() {
    var ctrl = this;
    this.$onInit = function() {
        ctrl.count = 0;
        ctrl.api = {};
        //Publish save function
        ctrl.api.save = save;
    };
    function save(){
      console.log("saved!");
      ctrl.count++;
    }
  }
});

그러면 부모 구성 요소가 자식을 호출할 수 있습니다.save공개된 API를 사용하여 함수:

ctrl.click = function(){
  console.log("Search clicked");
  ctrl.gridApi.save();
}

PLNKR의 데모.

여기 쉬운 방법이 있습니다: http://morrisdev.com/2017/03/triggering-events-in-a-child-component-in-angular/

기본적으로 "command"(또는 원하는 대로)라는 바인딩된 변수를 추가하고 $onChanges를 사용하여 해당 변수의 변경에 주의를 기울이고 수동으로 트리거하라는 이벤트가 표시되는 모든 것을 트리거합니다.

저는 개인적으로 모든 변수를 "설정"이라는 개체에 넣어 모든 구성 요소에 전송하는 것을 좋아합니다.그러나 개체 내의 값을 변경해도 $onChanges 이벤트가 트리거되지 않으므로 플랫 변수로 이벤트를 트리거하려면 해당 이벤트를 트리거해야 합니다.

"적절한" 방법은 아니지만 프로그래밍하기가 훨씬 쉽고 이해하기 쉬우며 나중에 A2로 변환하는 것도 훨씬 쉽습니다.

저도 같은 질문에 직면했습니다.이 접근 방식에 대해 어떻게 생각하십니까? 다음을 통해 상속을 사용하는 것입니다.require양방향 바인딩 대신에?

http://plnkr.co/edit/fD1qho3eoLoEnlvMzzbw?p=preview

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

    app.controller('RootController', function() {
    });

    app.component('filterComponent', {
      template: `
        <h3>Filter component</h3>
        <a class="btn btn-default btn-sm" ng-click="$ctrl.click()">Search</a>
        <span data-ng-bind="$ctrl.childMessage"></span>

        <grid-component api="$ctrl.gridApi"></grid-component>
      `,
      controller: function() {
        var ctrl = this;

        ctrl.click = function(){
          console.log("Search clicked");
          ctrl.gridApi.save();
        };
      }
    });

    app.component('gridComponent', {
      require: {parent:'^^filterComponent'},
      bindings: {api: "<"},
      template: `
        <h4>Grid component</h4>
        <p> Save count = {{$ctrl.count}}
      `,
      controller: function() {
        var ctrl = this;



        this.$onInit = function() {
            ctrl.count = 0;
            ctrl.api = {};
            ctrl.api.save = save;

            ctrl.parent.gridApi = ctrl.api;
        };
        function save(){
          console.log("saved!");
          ctrl.count++;
        }
      }
    });

또는 부모에게 세터 방식을 정의하여 보다 명확하게 할 수도 있습니다.

http://plnkr.co/edit/jmETwGt32BIn3Tl0yDzY?p=preview

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

app.controller('RootController', function() {
});

app.component('filterComponent', {
  template: `
    <h3>Filter component</h3>
    <a class="btn btn-default btn-sm" ng-click="$ctrl.click()">Search</a>
    <span data-ng-bind="$ctrl.childMessage"></span>

    <grid-component pass-api="$ctrl.setGridApi(api)"></grid-component>
  `,
  controller: function() {
    var ctrl = this;

    var gridApi = {};

    ctrl.setGridApi = function(api){
      gridApi = api;
    };

    ctrl.click = function(){
      console.log("Search clicked");
      gridApi.save();
    };
  }
});

app.component('gridComponent', {
  bindings: {
    passApi:'&'
  },
  template: `
    <h4>Grid component</h4>
    <p> Save count = {{$ctrl.count}}
  `,
  controller: function() {
    var ctrl = this;

    this.$onInit = function() {
        ctrl.count = 0;
        ctrl.api = {};
        ctrl.api.save = save;

        ctrl.passApi({api: ctrl.api});
    };
    function save(){
      console.log("saved!");
      ctrl.count++;
    }
  }
});

심플: 2방향 바인딩은 생성 시 변경사항만 호출하기 때문에 속성 1방향 바인딩 하나만 필요합니다.

  1. 상위 컨트롤러에 새 부울 속성을 설정합니다.

    vm.changeNow = false; //이를 vm.changeNow = !vm.changeNow 구성 요소에 메서드를 호출하도록 지시하려는 경우

  2. 자식 구성 요소 열기 바인딩 섹션에서

    바인딩: {a2waybind: '=', 지금 변경: '<' }

  3. 이제 자녀에 대한 $on Changes 이벤트가 필요합니다.

    $onChanges() { // 부모님께 듣고 싶었던 달콤한 말을 하세요. }

  4. 이제 템플릿을 호출할 때:

    하위 구성 요소 a2waybind="$ ctrl.mycool value "change now="$ctrl.change now" /childComponent"

두 번째 방법은 자식 구성 요소에 있습니다.

        var vm = this;
        var myprop;
        Object.defineProperty(vm, 'mytwowayprop', {
            get() {
                return myprop;
            },
            set(value) {
                myprop = value; 
                vm.onchangeseventbecausemypropchanged();               
            }
        });
       vm.onchangeseventbecausemypropchanged = function () {//woot}

이렇게 하면 양방향 바인딩 속성이 내부적으로나 외부적으로 변경될 때 변경에 대한 정의된 이벤트를 가질 수 있습니다.

언급URL : https://stackoverflow.com/questions/37439300/communicating-events-from-parent-to-child-in-angularjs-components