source

각도 간에 데이터 공유JS 컨트롤러

goodcode 2022. 10. 26. 22:20
반응형

각도 간에 데이터 공유JS 컨트롤러

컨트롤러 간에 데이터를 공유하려고 합니다.유스케이스는 다단계 형식이며, 한 입력으로 입력된 데이터는 나중에 원래 컨트롤러 외부에 있는 여러 디스플레이 위치에서 사용됩니다.아래 jsfiddle로 코드를 입력합니다.

HTML

<div ng-controller="FirstCtrl">
    <input type="text" ng-model="FirstName"><!-- Input entered here -->
    <br>Input is : <strong>{{FirstName}}</strong><!-- Successfully updates here -->
</div>

<hr>

<div ng-controller="SecondCtrl">
    Input should also be here: {{FirstName}}<!-- How do I automatically updated it here? -->
</div>

JS

// declare the app with no dependencies
var myApp = angular.module('myApp', []);

// make a factory to share data between controllers
myApp.factory('Data', function(){
    // I know this doesn't work, but what will?
    var FirstName = '';
    return FirstName;
});

// Step 1 Controller
myApp.controller('FirstCtrl', function( $scope, Data ){

});

// Step 2 Controller
myApp.controller('SecondCtrl', function( $scope, Data ){
    $scope.FirstName = Data.FirstName;
});

어떤 도움이라도 대단히 감사합니다.

간단한 해결책은 공장에서 개체를 반환하고 컨트롤러가 동일한 개체를 참조하도록 하는 것입니다.

JS:

// declare the app with no dependencies
var myApp = angular.module('myApp', []);

// Create the factory that share the Fact
myApp.factory('Fact', function(){
  return { Field: '' };
});

// Two controllers sharing an object that has a string in it
myApp.controller('FirstCtrl', function( $scope, Fact ){
  $scope.Alpha = Fact;
});

myApp.controller('SecondCtrl', function( $scope, Fact ){
  $scope.Beta = Fact;
});

HTML:

<div ng-controller="FirstCtrl">
    <input type="text" ng-model="Alpha.Field">
    First {{Alpha.Field}}
</div>

<div ng-controller="SecondCtrl">
<input type="text" ng-model="Beta.Field">
    Second {{Beta.Field}}
</div>

데모: http://jsfiddle.net/HEdJF/

어플리케이션이 커지고 복잡해지며 테스트하기 어려운 경우에는 공장에서 오브젝트 전체를 공개하지 않고 getter 및 setter를 통해 다음과 같이 제한적인 접근을 제공할 수 있습니다.

myApp.factory('Data', function () {

    var data = {
        FirstName: ''
    };

    return {
        getFirstName: function () {
            return data.FirstName;
        },
        setFirstName: function (firstName) {
            data.FirstName = firstName;
        }
    };
});

이 접근방식에서는 공장 출하 시 새로운 값으로 갱신하고 변경을 감시하는 것은 소비하는 컨트롤러에 달려 있습니다.

myApp.controller('FirstCtrl', function ($scope, Data) {

    $scope.firstName = '';

    $scope.$watch('firstName', function (newValue, oldValue) {
        if (newValue !== oldValue) Data.setFirstName(newValue);
    });
});

myApp.controller('SecondCtrl', function ($scope, Data) {

    $scope.$watch(function () { return Data.getFirstName(); }, function (newValue, oldValue) {
        if (newValue !== oldValue) $scope.firstName = newValue;
    });
});

HTML:

<div ng-controller="FirstCtrl">
  <input type="text" ng-model="firstName">
  <br>Input is : <strong>{{firstName}}</strong>
</div>
<hr>
<div ng-controller="SecondCtrl">
  Input should also be here: {{firstName}}
</div>

데모: http://jsfiddle.net/27mk1n1o/

는 사사 i i i i i i i i i i i는 쓰지 않는 편이 .$watch에 할당하는 아니라 할 수 있습니다.전체 서비스를 컨트롤러 범위에 할당하는 대신 데이터만 할당할 수 있습니다.

JS:

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

myApp.factory('MyService', function(){
  return {
    data: {
      firstName: '',
      lastName: ''
    }
    // Other methods or objects can go here
  };
});

myApp.controller('FirstCtrl', function($scope, MyService){
  $scope.data = MyService.data;
});

myApp.controller('SecondCtrl', function($scope, MyService){
   $scope.data = MyService.data;
});

HTML:

<div ng-controller="FirstCtrl">
  <input type="text" ng-model="data.firstName">
  <br>Input is : <strong>{{data.firstName}}</strong>
</div>
<hr>
<div ng-controller="SecondCtrl">
  Input should also be here: {{data.firstName}}
</div>

또는 직접 방법으로 서비스 데이터를 업데이트할 수 있습니다.

JS:

// A new factory with an update method
myApp.factory('MyService', function(){
  return {
    data: {
      firstName: '',
      lastName: ''
    },
    update: function(first, last) {
      // Improve this method as needed
      this.data.firstName = first;
      this.data.lastName = last;
    }
  };
});

// Your controller can use the service's update method
myApp.controller('SecondCtrl', function($scope, MyService){
   $scope.data = MyService.data;

   $scope.updateData = function(first, last) {
     MyService.update(first, last);
   }
});

컨트롤러 간에 데이터를 공유할 수 있는 방법은 여러 가지가 있습니다.

  1. 서비스 사용
  2. $state.go 서비스 사용
  3. 스테이트 파라미터 사용
  4. 루트 스코프 사용

각 방법에 대한 설명:

  1. 이미 누군가가 설명한 내용이기 때문에 설명하지 않을 것이다.

  2. 를 사용합니다.$state.go

      $state.go('book.name', {Name: 'XYZ'}); 
    
      // then get parameter out of URL
      $state.params.Name;
    
  3. $stateparam $state.go해, 「」, 「stateparam」을 사용해

  4. 를 사용합니다.$rootscope

    (a) 자녀에서 부모 컨트롤러로의 데이터 전송

      $scope.Save(Obj,function(data) {
          $scope.$emit('savedata',data); 
          //pass the data as the second parameter
      });
    
      $scope.$on('savedata',function(event,data) {
          //receive the data as second parameter
      }); 
    

    (b) 부모 컨트롤러에서 자녀 컨트롤러로의 데이터 전송

      $scope.SaveDB(Obj,function(data){
          $scope.$broadcast('savedata',data);
      });
    
      $scope.SaveDB(Obj,function(data){`enter code here`
          $rootScope.$broadcast('saveCallback',data);
      });
    

컨트롤러 간에 데이터를 공유하는 방법은 여러 가지가 있습니다.

  • 각도 서비스
  • $190, $190 메서드
  • 부모-자녀 컨트롤러 통신
  • $rootscope(루트스코프)

$rootscope는 어플리케이션 할 수 이기 때문에 또는 않습니다.

Angular Js는 Angular Js를 사용합니다. .factory,.service
참고용

컨트롤러로의 자녀 할 수 있습니다.$scope
「 」를 사용하고 ui-router그 후 를 사용할 수 있습니다.$stateParmas다음과 같은 URL 매개 변수를 전달합니다.id,name,key,기타

$broadcast부모에서 자녀로 컨트롤러 간에 데이터를 전송하는 좋은 방법이기도 합니다.$emit데이터를 하위 컨트롤러에서 상위 컨트롤러로 전송하다

HTML

<div ng-controller="FirstCtrl">
   <input type="text" ng-model="FirstName">
   <br>Input is : <strong>{{FirstName}}</strong>
</div>

<hr>

<div ng-controller="SecondCtrl">
   Input should also be here: {{FirstName}}
</div>

JS

myApp.controller('FirstCtrl', function( $rootScope, Data ){
    $rootScope.$broadcast('myData', {'FirstName': 'Peter'})
});

myApp.controller('SecondCtrl', function( $rootScope, Data ){
    $rootScope.$on('myData', function(event, data) {
       $scope.FirstName = data;
       console.log(data); // Check in console how data is coming
    });
});

자세한 내용은 지정된 링크를 참조하십시오.$broadcast

루트 경로 패턴 간의 공유 범위를 제어하는 팩토리를 작성했습니다.이것에 의해, 유저가 같은 루트 부모 패스를 네비게이트 하고 있을 때만, 공유 데이터를 유지할 수 있습니다.

.controller('CadastroController', ['$scope', 'RouteSharedScope',
    function($scope, routeSharedScope) {
      var customerScope = routeSharedScope.scopeFor('/Customer');
      //var indexScope = routeSharedScope.scopeFor('/');
    }
 ])

따라서 사용자가 다른 경로 경로(예: '/Support')로 이동하면 경로 '/Customer'의 공유 데이터가 자동으로 삭제됩니다.그러나 사용자가 '/Customer/1' 또는 '/Customer/list'와 같은 '자녀' 경로로 이동하는 경우 범위가 파괴되지 않습니다.

샘플은, http://plnkr.co/edit/OL8of9 를 참조해 주세요.

가장 심플한 솔루션:

Angular를 사용했습니다.JS 서비스

1단계: Angular를 작성했습니다.SharedDataService라는 이름의 JS 서비스입니다.

myApp.service('SharedDataService', function () {
     var Person = {
        name: ''

    };
    return Person;
});

스텝 2: 2개의 컨트롤러를 생성하여 위에서 작성한 서비스를 사용합니다.

//First Controller
myApp.controller("FirstCtrl", ['$scope', 'SharedDataService',
   function ($scope, SharedDataService) {
   $scope.Person = SharedDataService;
   }]);

//Second Controller
myApp.controller("SecondCtrl", ['$scope', 'SharedDataService',
   function ($scope, SharedDataService) {
   $scope.Person = SharedDataService;
   }]);

스텝 3: 뷰에서 작성한 컨트롤러를 사용하면 됩니다.

<body ng-app="myApp">

<div ng-controller="FirstCtrl">
<input type="text" ng-model="Person.name">
<br>Input is : <strong>{{Person.name}}</strong>
</div>

<hr>

<div ng-controller="SecondCtrl">
Input should also be here: {{Person.name}}
</div>

</body>

이 문제에 대한 유효한 해결책을 보려면 아래 링크를 클릭하십시오.

https://codepen.io/wins/pen/bmoYLr

.filename 파일:

<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>

<body ng-app="myApp">

  <div ng-controller="FirstCtrl">
    <input type="text" ng-model="Person.name">
    <br>Input is : <strong>{{Person.name}}</strong>
   </div>

<hr>

  <div ng-controller="SecondCtrl">
    Input should also be here: {{Person.name}}
  </div>

//Script starts from here

<script>

var myApp = angular.module("myApp",[]);
//create SharedDataService
myApp.service('SharedDataService', function () {
     var Person = {
        name: ''

    };
    return Person;
});

//First Controller
myApp.controller("FirstCtrl", ['$scope', 'SharedDataService',
    function ($scope, SharedDataService) {
    $scope.Person = SharedDataService;
    }]);

//Second Controller
myApp.controller("SecondCtrl", ['$scope', 'SharedDataService',
    function ($scope, SharedDataService) {
    $scope.Person = SharedDataService;
}]);

</script>


</body>
</html>

$watch를 사용하지 않고 angular.copy를 사용하는 다른 방법이 있습니다.

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

myApp.factory('Data', function(){

    var service = {
        FirstName: '',
        setFirstName: function(name) {
            // this is the trick to sync the data
            // so no need for a $watch function
            // call this from anywhere when you need to update FirstName
            angular.copy(name, service.FirstName); 
        }
    };
    return service;
});


// Step 1 Controller
myApp.controller('FirstCtrl', function( $scope, Data ){

});

// Step 2 Controller
myApp.controller('SecondCtrl', function( $scope, Data ){
    $scope.FirstName = Data.FirstName;
});

여기에는 여러 가지 방법이 있습니다.

  1. 이벤트 - 이미 잘 설명되었습니다.

  2. ui 라우터 - 위에서 설명했습니다.

  3. 서비스 - 위에 표시된 업데이트 방법
  4. 불량 - 변경을 감시하고 있습니다.
  5. 방출 및 브로드캐스트아닌 또 다른 부모 자녀 접근법 -

*

<superhero flight speed strength> Superman is here! </superhero>
<superhero speed> Flash is here! </superhero>

*

app.directive('superhero', function(){
    return {
        restrict: 'E',
        scope:{}, // IMPORTANT - to make the scope isolated else we will pollute it in case of a multiple components.
        controller: function($scope){
            $scope.abilities = [];
            this.addStrength = function(){
                $scope.abilities.push("strength");
            }
            this.addSpeed = function(){
                $scope.abilities.push("speed");
            }
            this.addFlight = function(){
                $scope.abilities.push("flight");
            }
        },
        link: function(scope, element, attrs){
            element.addClass('button');
            element.on('mouseenter', function(){
               console.log(scope.abilities);
            })
        }
    }
});
app.directive('strength', function(){
    return{
        require:'superhero',
        link: function(scope, element, attrs, superHeroCtrl){
            superHeroCtrl.addStrength();
        }
    }
});
app.directive('speed', function(){
    return{
        require:'superhero',
        link: function(scope, element, attrs, superHeroCtrl){
            superHeroCtrl.addSpeed();
        }
    }
});
app.directive('flight', function(){
    return{
        require:'superhero',
        link: function(scope, element, attrs, superHeroCtrl){
            superHeroCtrl.addFlight();
        }
    }
});

이 패턴을 어디서 배웠는지 모르겠지만 컨트롤러 간에 데이터를 공유하고 $rootScope와 $scope를 줄이는 것이 효과적입니다.퍼블리셔와 서브스크라이버가 있는 경우의 데이터 레플리케이션을 연상시킵니다.도움이 됐으면 좋겠다.

서비스:

(function(app) {
    "use strict";
    app.factory("sharedDataEventHub", sharedDataEventHub);

    sharedDataEventHub.$inject = ["$rootScope"];

    function sharedDataEventHub($rootScope) {
        var DATA_CHANGE = "DATA_CHANGE_EVENT";
        var service = {
            changeData: changeData,
            onChangeData: onChangeData
        };
        return service;

        function changeData(obj) {
            $rootScope.$broadcast(DATA_CHANGE, obj);
        }

        function onChangeData($scope, handler) {
            $scope.$on(DATA_CHANGE, function(event, obj) {
                handler(obj);
            });
        }
    }
}(app));

새로운 데이터를 취득하는 컨트롤러, 즉 퍼블리셔는 다음과 같은 처리를 합니다.

var someData = yourDataService.getSomeData();

sharedDataEventHub.changeData(someData);

서브스크라이버라고 불리는 이 새로운 데이터를 사용하는 컨트롤러는 다음과 같은 작업을 수행합니다.

sharedDataEventHub.onChangeData($scope, function(data) {
    vm.localData.Property1 = data.Property1;
    vm.localData.Property2 = data.Property2;
});

이것은, 모든 시나리오에 대응합니다.따라서 프라이머리 컨트롤러가 초기화되어 데이터를 취득하면 changeData 메서드를 호출하여 해당 데이터의 모든 가입자에게 브로드캐스트합니다.이로 인해 컨트롤러 간의 결합이 감소합니다.

@MaNn이 수락한 답변 중 하나의 코멘트에서 지적했듯이 페이지를 새로 고치면 해결 방법이 작동하지 않습니다.

이 문제를 해결하려면 컨트롤러 간에 공유할 데이터의 임시 영속성을 위해 local스토리지 또는 sessionStorage를 사용합니다.

  1. GET 및 SET 메서드가 데이터를 암호화 및 해독하고 localStorage 또는 sessionStorage에서 데이터를 읽는 sessionService를 만듭니다.이제 이 서비스를 사용하여 원하는 컨트롤러 또는 서비스를 통해 스토리지의 데이터를 직접 읽고 쓸 수 있습니다.이것은 개방적이고 쉬운 접근법이다.
  2. 그렇지 않으면 DataSharing Service를 만들고 그 안에서 localStorage를 사용합니다.그러면 페이지가 새로 고쳐지면 서비스가 스토리지를 확인하고 이 서비스 파일에서 공개 또는 비공개한 Getters 및 Setters를 통해 회신합니다.

간단하게 (v1.3.15에서 테스트 완료):

<article ng-controller="ctrl1 as c1">
    <label>Change name here:</label>
    <input ng-model="c1.sData.name" />
    <h1>Control 1: {{c1.sData.name}}, {{c1.sData.age}}</h1>
</article>
<article ng-controller="ctrl2 as c2">
    <label>Change age here:</label>
    <input ng-model="c2.sData.age" />
    <h1>Control 2: {{c2.sData.name}}, {{c2.sData.age}}</h1>
</article>

<script>
    var app = angular.module("MyApp", []);

    var dummy = {name: "Joe", age: 25};

    app.controller("ctrl1", function () {
        this.sData = dummy;
    });

    app.controller("ctrl2", function () {
        this.sData = dummy;
    });
</script>

언급URL : https://stackoverflow.com/questions/21919962/share-data-between-angularjs-controllers

반응형