[javascript] AngularJS : 컨트롤러간에 변수를 전달하는 방법은 무엇입니까?

두 개의 Angular 컨트롤러가 있습니다.

function Ctrl1($scope) {
    $scope.prop1 = "First";
}

function Ctrl2($scope) {
    $scope.prop2 = "Second";
    $scope.both = Ctrl1.prop1 + $scope.prop2; //This is what I would like to do ideally
}

정의되지 않았기 때문에 Ctrl1내부를 사용할 수 없습니다 Ctrl2. 그러나 내가 그렇게 전달하려고하면 …

function Ctrl2($scope, Ctrl1) {
    $scope.prop2 = "Second";
    $scope.both = Ctrl1.prop1 + $scope.prop2; //This is what I would like to do ideally
}

오류가 발생합니다. 누구든지 이것을하는 방법을 알고 있습니까?

하기

Ctrl2.prototype = new Ctrl1();

또한 실패합니다.

참고 : 이 컨트롤러는 서로 중첩되어 있지 않습니다.



답변

여러 컨트롤러에서 변수를 공유하는 한 가지 방법 은 서비스만들고 사용하려는 컨트롤러에 서비스 를 삽입하는 것입니다.

간단한 서비스 예 :

angular.module('myApp', [])
    .service('sharedProperties', function () {
        var property = 'First';

        return {
            getProperty: function () {
                return property;
            },
            setProperty: function(value) {
                property = value;
            }
        };
    });

컨트롤러에서 서비스 사용 :

function Ctrl2($scope, sharedProperties) {
    $scope.prop2 = "Second";
    $scope.both = sharedProperties.getProperty() + $scope.prop2;
}

이것은 이 블로그 (레슨 2 이상) 에서 매우 잘 설명 되어 있습니다.

여러 컨트롤러에서 이러한 속성에 바인딩하려는 경우 바인딩 된 참조를 유지하기 위해 기본 유형 (부울, 문자열, 숫자) 대신 객체의 속성에 바인딩하면 더 잘 작동합니다.

예 : var property = { Property1: 'First' };대신 var property = 'First';.


업데이트 : 여기에 더 명확하게하기 위해 다음과 같은 예를 보여주는 바이올린 이 있습니다.

  • 공유 값의 정적 사본에 바인딩 (myController1에서)
    • 프리미티브 (문자열)에 바인딩
    • 개체 속성에 바인딩 (범위 변수에 저장)
  • 값이 업데이트 될 때 UI를 업데이트하는 공유 값에 바인딩 (myController2에서)
    • 기본 (문자열)을 반환하는 함수에 바인딩
    • 객체의 속성에 바인딩
    • 객체의 속성에 대한 양방향 바인딩

답변

나는 간단한 예제를 통해 간단한 것들을 설명하고 싶습니다 🙂

다음은 매우 간단한 Service예입니다.


angular.module('toDo',[])

.service('dataService', function() {

  // private variable
  var _dataObj = {};

  // public API
  this.dataObj = _dataObj;
})

.controller('One', function($scope, dataService) {
  $scope.data = dataService.dataObj;
})

.controller('Two', function($scope, dataService) {
  $scope.data = dataService.dataObj;
});

그리고 여기 jsbin

그리고 여기 아주 간단한 Factory예가 있습니다 :


angular.module('toDo',[])

.factory('dataService', function() {

  // private variable
  var _dataObj = {};

  // public API
  return {
    dataObj: _dataObj
  };
})

.controller('One', function($scope, dataService) {
  $scope.data = dataService.dataObj;
})

.controller('Two', function($scope, dataService) {
  $scope.data = dataService.dataObj;
});

그리고 여기 jsbin


그것이 너무 간단한 경우, 여기에 더 정교한 예가 있습니다

또한 관련 모범 사례의 의견에 대한 대답은 여기를 참조


답변

— 나는이 답변이이 질문에 대한 것이 아니라는 것을 알고 있지만,이 질문을 읽고 문제를 피하기 위해 공장과 같은 서비스를 처리하려는 사람들을 원합니다 —-

이를 위해서는 서비스 또는 팩토리를 사용해야합니다.

서비스는 중첩되지 않은 컨트롤러간에 데이터를 공유 하는 최선의 방법 입니다.

데이터 공유에 대한이 주제에 대한 아주 좋은 주석은 객체를 선언하는 방법입니다. 나는 그것에 대해 읽기 전에 AngularJS 함정에 빠졌기 때문에 운이 좋지 않았고 매우 좌절했습니다. 이 문제를 피할 수 있도록 도와 드리겠습니다.

나는 “ng-book : AngularJS에 관한 완전한 책”에서 읽은 데이터로 컨트롤러에서 생성 된 AngularJS ng 모델이 잘못되었다는 것을 읽었습니다!

$ scope 요소는 다음과 같이 만들어야합니다.

angular.module('myApp', [])
.controller('SomeCtrl', function($scope) {
  // best practice, always use a model
  $scope.someModel = {
    someValue: 'hello computer'
  });

그리고 이것처럼 :

angular.module('myApp', [])
.controller('SomeCtrl', function($scope) {
  // anti-pattern, bare value
  $scope.someBareValue = 'hello computer';
  };
});

DOM (html document)이 다음과 같이 호출을 포함하도록 권장 (BEST PRACTICE)되기 때문입니다.

<div ng-model="someModel.someValue"></div>  //NOTICE THE DOT.

자식 컨트롤러가 부모 컨트롤러에서 개체를 변경할 수있게하려면 중첩 컨트롤러에 매우 유용합니다.

그러나 귀하의 경우 중첩 범위를 원하지 않지만 서비스에서 컨트롤러로 객체를 가져 오는 것과 비슷한 측면이 있습니다.

서비스 ‘Factory’가 있고 리턴 공간에 objectC를 포함하는 objectB를 포함하는 objectA가 있다고 가정 해 봅시다.

컨트롤러에서 objectC를 범위로 가져 오려는 경우 실수입니다.

$scope.neededObjectInController = Factory.objectA.objectB.objectC;

작동하지 않습니다 …
대신 점 하나만 사용하십시오.

$scope.neededObjectInController = Factory.ObjectA;

그런 다음 DOM에서 objectA에서 objectC를 호출 할 수 있습니다. 이것은 공장과 관련된 모범 사례이며, 가장 중요한 것은 예기치 않은 캐치 불가능 오류를 피하는 데 도움이됩니다.


답변

$ rootScope를 사용하여 서비스를 작성하지 않은 솔루션 :

앱 컨트롤러간에 속성을 공유하려면 Angular $ rootScope를 사용할 수 있습니다. 이것은 사람들이 정보를 알 수 있도록 데이터를 공유하는 또 다른 옵션입니다.

Controllers에서 일부 기능을 공유하는 선호되는 방법은 Services, $ rootscope를 사용할 수있는 전역 속성을 읽거나 변경하는 것입니다.

var app = angular.module('mymodule',[]);
app.controller('Ctrl1', ['$scope','$rootScope',
  function($scope, $rootScope) {
    $rootScope.showBanner = true;
}]);

app.controller('Ctrl2', ['$scope','$rootScope',
  function($scope, $rootScope) {
    $rootScope.showBanner = false;
}]);

템플리트에서 $ rootScope 사용 ($ root를 사용하여 액세스 특성) :

<div ng-controller="Ctrl1">
    <div class="banner" ng-show="$root.showBanner"> </div>
</div>


답변

위의 샘플은 매력처럼 작동했습니다. 여러 값을 관리 해야하는 경우를 대비하여 수정했습니다. 이게 도움이 되길 바란다!

app.service('sharedProperties', function () {

    var hashtable = {};

    return {
        setValue: function (key, value) {
            hashtable[key] = value;
        },
        getValue: function (key) {
            return hashtable[key];
        }
    }
});


답변

나는 이것이 왜 나쁜 생각인지 토론 할 수있는 값을 사용하는 경향이있다.

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

myApp.value('sharedProperties', {}); //set to empty object - 

그런 다음 서비스별로 값을 주입하십시오.

ctrl1에서 설정하십시오.

myApp.controller('ctrl1', function DemoController(sharedProperties) {
  sharedProperties.carModel = "Galaxy";
  sharedProperties.carMake = "Ford";
});

ctrl2에서 액세스하십시오.

myApp.controller('ctrl2', function DemoController(sharedProperties) {
  this.car = sharedProperties.carModel + sharedProperties.carMake;

});


답변

다음 예에 도시 한 방법과 변수 통과 형제의 컨트롤러 값이 변경 될 때 동작을 수행.

사용 사례 : 사이드 바에 다른보기의 내용을 변경하는 필터가 있습니다.

angular.module('myApp', [])

  .factory('MyService', function() {

    // private
    var value = 0;

    // public
    return {

      getValue: function() {
        return value;
      },

      setValue: function(val) {
        value = val;
      }

    };
  })

  .controller('Ctrl1', function($scope, $rootScope, MyService) {

    $scope.update = function() {
      MyService.setValue($scope.value);
      $rootScope.$broadcast('increment-value-event');
    };
  })

  .controller('Ctrl2', function($scope, MyService) {

    $scope.value = MyService.getValue();

    $scope.$on('increment-value-event', function() {
      $scope.value = MyService.getValue();
    });
  });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="myApp">

  <h3>Controller 1 Scope</h3>
  <div ng-controller="Ctrl1">
    <input type="text" ng-model="value"/>
    <button ng-click="update()">Update</button>
  </div>

  <hr>

  <h3>Controller 2 Scope</h3>
  <div ng-controller="Ctrl2">
    Value: {{ value }}
  </div>

</div>