programing

$scope를 사용하지 않고 형제 컴포넌트 간에 데이터를 전달하려면 어떻게 해야 합니까?

fastcode 2023. 3. 21. 22:37
반응형

$scope를 사용하지 않고 형제 컴포넌트 간에 데이터를 전달하려면 어떻게 해야 합니까?

다음과 같은 방법으로 3개의 하위 구성 요소를 포함하는 구성 요소를 만들고 있습니다.

<header-component>
<side-component>
<main-component>

주요 구성 요소에는 영웅 목록이 포함되어 있습니다.헤더 컴포넌트에는 메인컴포넌트의 뷰를 리스트뷰 또는 그리드뷰로 전환하는2개의 버튼이 있습니다.

현재 문제는 헤더 컴포넌트에서 메인 컴포넌트로 데이터를 전달하는 것입니다.따라서 그리드 버튼을 클릭하면 메인 콘텐츠의 뷰가 열 뷰와 마찬가지로 그리드 뷰로 변경됩니다.

데이터는 각 1.5의 하위 구성 요소 간에 어떻게 전달될 수 있습니까?

컴포넌트 어프로치

Angular 2 컴포넌트 접근법에 맞춰 입력/출력 접근법을 사용하는 이 좋습니다.이렇게 하면 구성 요소가 개념적으로 동일하기 때문에 Angular 2로 쉽게 마이그레이션할 수 있습니다(구문만 다릅니다).그럼 이렇게 하는군요.

따라서 기본적으로 헤더와 주요 컴포넌트가 상태를 헤더와 공유하여 변경할 수 있도록 해야 합니다.동작시키기 위해 사용할 수 있는 방법은 여러 가지가 있지만 가장 간단한 방법은 중간 부모 컨트롤러 속성을 사용하는 것입니다. 컴포넌트가 이 컨트롤러(또는 컴포넌트)를 하고 있다고 view헤더(읽고 수정할 수 있음)와 메인(읽을 수 있음) 컴포넌트 모두에서 사용할 속성입니다.

헤더 컴포넌트: 입력 및 출력.

간단한 헤더 컴포넌트는 다음과 같습니다.

.component('headerComponent', {
  template: `
    <h3>Header component</h3>
    <a ng-class="{'btn-primary': $ctrl.view === 'list'}" ng-click="$ctrl.setView('list')">List</a>
    <a ng-class="{'btn-primary': $ctrl.view === 'table'}" ng-click="$ctrl.setView('table')">Table</a>
  `,
  controller: function() {
    this.setView = function(view) {
      this.view = view
      this.onViewChange({$event: {view: view}})
    }
  },
  bindings: {
    view: '<',
    onViewChange: '&'
  }
})

여기서 가장 중요한 부분은 바인딩입니다.★★★★★★★★★★★★★★★★ view: '<'하고 있습니다.header는 외부 을 '바인드'로 수 .view이치노★★★★★★★★★★★★★★★★ onViewChange: '&'컴포넌트 정의 출력: 외부 세계에 필요한 모든 것을 통지/통보하는 채널.헤더 컴포넌트는 일부 데이터를 이 채널을 통해 푸시하지만 부모 컴포넌트가 이 채널로 무엇을 할지는 모르기 때문에 상관하지 않습니다.

...header는 '컨트롤러'를할 수 .

<header-component view="root.view" on-view-change="root.view = $event.view"></header-component> 

주요 컴포넌트: 입력.

메인 컴포넌트는 보다 심플합니다.인풋을 정의하기만 하면 됩니다.

.component('mainComponent', {
  template: `
    <h4>Main component</h4>
    Main view: {{ $ctrl.view }}
  `,
  bindings: {
    view: '<'
  }
})

부모 뷰

그리고 마침내 모든 것이 연결되었습니다.

<header-component view="root.view" on-view-change="root.view = $event.view"></header-component>
<main-component view="root.view"></main-component>

간단한 데모를 통해 확인해 보십시오.

angular.module('demo', [])

.controller('RootController', function() {
  this.view = 'table'
})

.component('headerComponent', {
  template: `
    <h3>Header component</h3>
    <a class="btn btn-default btn-sm" ng-class="{'btn-primary': $ctrl.view === 'list'}" ng-click="$ctrl.setView('list')">List</a>
    <a class="btn btn-default btn-sm" ng-class="{'btn-primary': $ctrl.view === 'table'}" ng-click="$ctrl.setView('table')">Table</a>
  `,
  controller: function() {
    this.setView = function(view) {
      this.view = view
      this.onViewChange({$event: {view: view}})
    }
  },
  bindings: {
    view: '<',
    onViewChange: '&'
  }
})

.component('mainComponent', {
  template: `
    <h4>Main component</h4>
    Main view: {{ $ctrl.view }}
  `,
  bindings: {
    view: '<'
  }
})
<script src="https://code.angularjs.org/1.5.0/angular.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.css" />

<div class="container" ng-app="demo" ng-controller="RootController as root">
  
    <pre>Root view: {{ root.view }}</pre>
    
    <header-component view="root.view" on-view-change="root.view = $event.view"></header-component>
    <main-component view="root.view"></main-component>
    
</div>

데모: http://plnkr.co/edit/ODuY5Mp9HhbqA31G4w3t?p=info


다음은 컴포넌트 기반 설계에 대해 자세히 설명한 블로그 게시물입니다.http://dfsq.info/site/read/angular-components-communication

부모 컴포넌트 접근법(속성을 통해 데이터를 전달하는 방법)은 완벽하지만 우수한 구현이지만 스토어 팩토리를 사용하면 동일한 작업을 보다 쉽게 수행할 수 있습니다.

으로 데이터는 본본에 의해 됩니다.Store두 컴포넌트 범위에서 모두 참조되므로 상태가 변경되었을 때 UI를 자동으로 업데이트할 수 있습니다.

예:

angular
    .module('YourApp')
    // declare the "Store" or whatever name that make sense
    // for you to call it (Model, State, etc.)
    .factory('Store', () => {
        // hold a local copy of the state, setting its defaults
        const state = {
            data: {
              heroes: [],
              viewType: 'grid'
            }
        };
        // expose basic getter and setter methods
        return {
            get() {
                return state.data;
            },
            set(data) {
                Object.assign(state.data, data);
            },
        };
    });

다음으로 컴포넌트에는 다음과 같은 것이 있습니다.

angular
    .module('YourApp')
    .component('headerComponent', {
        // inject the Store dependency
        controller(Store) {
            // get the store reference and bind it to the scope:
            // now, every change made to the store data will
            // automatically update your component UI
            this.state = Store.get();

            // ... your code
        },
        template: `
            <div ng-show="$ctrl.state.viewType === 'grid'">...</div>
            <div ng-show="$ctrl.state.viewType === 'row'">...</div>
            ...
        `
    })
    .component('mainComponent', {
        // same here, we need to inject the Store
        controller(Store) {
            // callback for the switch view button
            this.switchViewType = (type) => {
                // change the Store data:
                // no need to notify or anything
                Store.set({ viewType: type });
            };

            // ... your code
        },
        template: `
            <button ng-click="$ctrl.switchViewType('grid')">Switch to grid</button>
            <button ng-click="$ctrl.switchViewType('row')">Switch to row</button>
            ...
        `

작업 예를 보려면 이 CodePen을 확인하십시오.

이렇게 하면 2개의 컴포넌트 또는N개의 컴포넌트간의 통신을 유효하게 할 수도 있습니다.다음 작업만 하면 됩니다.

  1. 점포 의존도를 높이다
  2. 스토어 데이터를 컴포넌트 스코프에 링크하고 있는지 확인합니다.

( 「」를 참조해 주세요).<header-component>를 참조해 주세요.

실제 환경에서는 일반적인 애플리케이션이 많은 데이터를 관리해야 하므로 어떤 방식으로든 데이터 도메인을 논리적으로 분할하는 것이 더 합리적입니다.같은 방법으로 스토어 팩토리를 추가할 수 있습니다.예를 들어, 현재 기록된 사용자 정보와 외부 리소스(예: 카탈로그)를 관리하기 위해UserStore a도CatalogStore -----------------------------------UserModel ★★★★★★★★★★★★★★★★★」CatalogModel또한 백엔드와의 통신, 커스텀 비즈니스 로직 추가중앙 집중화에도 적합합니다.데이터 관리는 다음 중 하나의 책임입니다.Store★★★★★★ 。

스토어 데이터를 변환하고 있습니다.이 접근방식은 매우 간단하고 명확하지만 부작용이 발생하기 때문에 확장성이 좋지 않을 수 있습니다.고급 기능(불변성, 순수 함수, 단일 상태 트리 등)을 원하는 경우 Redux를 확인하거나 Angular 2로 전환하려면 ngrx/store를 확인하십시오.

이것이 도움이 되기를! :)

Angular 2 방식으로 할 필요는 없어요. 왜냐하면 당신이 가끔 이주할 경우를 대비해서...네가 하는 것이 말이 된다면 그것을 해라.

이벤트 디스패처를 사용하여 할 수 .$emit(name, args); or $broadcast(name, args);또한 $on(이름, 청취자) 메서드를 사용하여 이 이벤트를 청취할 수 있습니다.

도움이 되었으면 좋겠다

참고 자료: https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$emit

예: 헤더 컴포넌트에서 다음과 같은 변경을 통지할 수 있습니다.

$rootScope.$emit("menu-changed", "list");

그리고 당신은 당신의 주요 구성 요소 지시의 변화를 들을 수 있습니다.

$rootScope.$on("menu-changed", function(evt, arg){
  console.log(arg);
});

언급URL : https://stackoverflow.com/questions/36033940/how-to-pass-data-between-sibling-components-without-using-scope

반응형