AngularJS 컨트롤러간에 데이터 공유
컨트롤러간에 데이터를 공유하려고합니다. 유스 케이스는 다단계 양식이며 한 입력에 입력 된 데이터는 나중에 원래 컨트롤러 외부의 여러 표시 위치에서 사용됩니다. 아래와 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/
나는 $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);
}
});
컨트롤러간에 데이터를 공유 할 수있는 많은 방법이 있습니다
- 서비스 사용
- $ state.go 서비스 사용
- stateparams 사용
- 루트 스코프 사용
각 방법에 대한 설명 :
나는 누군가가 이미 설명 한대로 설명하지 않을 것입니다
사용
$state.go
$state.go('book.name', {Name: 'XYZ'}); // then get parameter out of URL $state.params.Name;
$stateparam
와 비슷한 방식으로 작동하며$state.go
송신자 컨트롤러에서 객체로 객체를 전달하고 stateparam을 사용하여 수신기 컨트롤러에서 수집합니다.사용
$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); });
경로 경로 패턴 사이의 공유 범위를 제어하는 팩토리를 만들었으므로 사용자가 동일한 경로 상위 경로를 탐색 할 때만 공유 데이터를 유지할 수 있습니다.
.controller('CadastroController', ['$scope', 'RouteSharedScope',
function($scope, routeSharedScope) {
var customerScope = routeSharedScope.scopeFor('/Customer');
//var indexScope = routeSharedScope.scopeFor('/');
}
])
따라서 사용자가 다른 경로 경로 (예 : '/ Support')로 이동하면 경로 '/ Customer'에 대한 공유 데이터가 자동으로 삭제됩니다. 그러나이 대신 사용자가 '/ Customer / 1'또는 '/ Customer / list'와 같은 'child'경로로 이동하면 범위가 손상되지 않습니다.
여기에서 샘플을 볼 수 있습니다 : http://plnkr.co/edit/OL8of9
컨트롤러간에 데이터를 공유하는 방법에는 여러 가지가 있습니다
- 각도 서비스
- 브로드 캐스트, $ emit 방법
- 부모-자식 컨트롤러 통신
- $ rootscope
우리가 알고 있듯이 $rootscope
데이터 전송 또는 통신에 바람직하지 않은 방법은 전체 응용 프로그램에서 사용할 수있는 전역 범위이므로
Angular Js 컨트롤러 간의 데이터 공유를 위해 Angular 서비스는 모범 사례입니다. .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
가장 간단한 해결책 :
AngularJS 서비스를 사용했습니다 .
1 단계 : SharedDataService라는 AngularJS 서비스를 만들었습니다.
myApp.service('SharedDataService', function () {
var Person = {
name: ''
};
return Person;
});
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
.html 파일 :
<!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>
angular.copy를 사용하여 $ watch를 사용하지 않는 다른 방법이 있습니다.
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;
});
여러 가지 방법이 있습니다.
이벤트-이미 잘 설명했습니다.
UI 라우터-위에서 설명했습니다.
- 서비스-위에 표시된 업데이트 방법
- BAD- 변경 사항 감시
- 보다는 또 다른 부모 자식 접근 개의 발광 과 의 브로드 캐스트 -
*
<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));
새 데이터를 가져 오는 Controller (Publisher)는 이와 같은 작업을 수행합니다.
var someData = yourDataService.getSomeData();
sharedDataEventHub.changeData(someData);
구독자라고하는이 새로운 데이터를 사용하는 컨트롤러는 다음과 같은 작업을 수행합니다.
sharedDataEventHub.onChangeData($scope, function(data) {
vm.localData.Property1 = data.Property1;
vm.localData.Property2 = data.Property2;
});
이것은 모든 시나리오에서 작동합니다. 따라서 기본 컨트롤러가 초기화되고 데이터를 가져 오면 changeData 메서드를 호출하여 해당 데이터의 모든 가입자에게 브로드 캐스트합니다. 이를 통해 컨트롤러의 커플 링이 줄어 듭니다.
간단하게 (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
'development' 카테고리의 다른 글
EXE를 출력하기 위해 .NET Core 콘솔 응용 프로그램을 빌드 하시겠습니까? (0) | 2020.02.29 |
---|---|
빈 Pandas DataFrame을 만든 다음 채우시겠습니까? (0) | 2020.02.29 |
바이트 + 바이트 = int… 왜? (0) | 2020.02.29 |
PreferenceActivity에서 "addPreferencesFromResource"대신 무엇을 사용해야합니까? (0) | 2020.02.29 |
Spring Framework에서 applicationContext.xml과 spring-servlet.xml의 차이점 (0) | 2020.02.29 |