[javascript] AngularJS 컨트롤러를 확장하는 데 권장되는 방법은 무엇입니까?

꽤 비슷한 세 개의 컨트롤러가 있습니다. 이 세 가지 기능을 확장하고 공유하는 컨트롤러를 갖고 싶습니다.



답변

아마도 당신은 컨트롤러를 확장하지 않습니다하지만 컨트롤러를 확장하거나 하나의 컨트롤러를 여러 컨트롤러의 믹스 인을 만드는 것이 가능하다.

module.controller('CtrlImplAdvanced', ['$scope', '$controller', function ($scope, $controller) {
    // Initialize the super class and extend it.
    angular.extend(this, $controller('CtrlImpl', {$scope: $scope}));
     Additional extensions to create a mixin.
}]);

상위 컨트롤러가 생성되면 그 안에 포함 된 로직도 실행됩니다. $scope값만 전달 하면되지만 자세한 내용은 $ controller ()를 참조하십시오 . 다른 모든 값은 정상적으로 주입됩니다.

@mwarren , Angular 의존성 주입으로 문제를 자동으로 처리합니다. 필요한 경우 $ scope를 주입하기 만하면되지만 원하는 경우 다른 주입 된 값을 무시할 수 있습니다. 다음 예제를 보자.

(function(angular) {

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

	module.controller('simpleController', function($scope, $document) {
		this.getOrigin = function() {
			return $document[0].location.origin;
		};
	});

	module.controller('complexController', function($scope, $controller) {
		angular.extend(this, $controller('simpleController', {$scope: $scope}));
	});

})(angular);
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular.js"></script>

<div ng-app="stackoverflow.example">
    <div ng-controller="complexController as C">
        <span><b>Origin from Controller:</b> {{C.getOrigin()}}</span>
    </div>
</div>

‘complexController’에 의해 생성 될 때 $ document가 ‘simpleController’에 전달되지 않지만 $ document가 우리에게 주입됩니다.


답변

상속을 위해 표준 JavaScript 상속 패턴을 사용할 수 있습니다. 다음은 사용하는 데모입니다$injector

function Parent($scope) {
  $scope.name = 'Human';
  $scope.clickParent = function() {
    $scope.name = 'Clicked from base controller';
  }
}

function Child($scope, $injector) {
  $injector.invoke(Parent, this, {$scope: $scope});
  $scope.name = 'Human Child';
  $scope.clickChild = function(){
    $scope.clickParent();
  }
}

Child.prototype = Object.create(Parent.prototype);

controllerAs구문 을 사용하는 경우 (내가 권장하는) 고전 상속 패턴을 사용하는 것이 훨씬 쉽습니다.

function BaseCtrl() {
  this.name = 'foobar';
}
BaseCtrl.prototype.parentMethod = function () {
  //body
};

function ChildCtrl() {
  BaseCtrl.call(this);
  this.name = 'baz';
}
ChildCtrl.prototype = Object.create(BaseCtrl.prototype);
ChildCtrl.prototype.childMethod = function () {
  this.parentMethod();
  //body
};

app.controller('BaseCtrl', BaseCtrl);
app.controller('ChildCtrl', ChildCtrl);

또 다른 방법은 기본 컨트롤러가되는 “추상적 인”생성자 함수를 만드는 것입니다.

function BaseController() {
  this.click = function () {
    //some actions here
  };
}

module.controller('ChildCtrl', ['$scope', function ($scope) {
  BaseController.call($scope);
  $scope.anotherClick = function () {
    //other actions
  };
}]);

이 주제에 대한 블로그 게시물


답변

글쎄, 나는 당신이 무엇을 달성하고자하는지 확실하지 않지만 일반적으로 서비스가 갈 길입니다. Angular의 스코프 상속 특성을 사용하여 컨트롤러간에 코드를 공유 할 수도 있습니다.

<body ng-controller="ParentCtrl">
 <div ng-controller="FirstChildCtrl"></div>
 <div ng-controller="SecondChildCtrl"></div>
</body>

function ParentCtrl($scope) {
 $scope.fx = function() {
   alert("Hello World");
 });
}

function FirstChildCtrl($scope) {
  // $scope.fx() is available here
}

function SecondChildCtrl($scope) {
  // $scope.fx() is available here
}


답변

컨트롤러를 확장하지 않습니다. 동일한 기본 기능을 수행하는 경우 해당 기능을 서비스로 이동해야합니다. 이 서비스는 컨트롤러에 주입 할 수 있습니다.


답변

기사 에서 얻은 또 다른 좋은 해결책 :

// base controller containing common functions for add/edit controllers
module.controller('Diary.BaseAddEditController', function ($scope, SomeService) {
    $scope.diaryEntry = {};

    $scope.saveDiaryEntry = function () {
        SomeService.SaveDiaryEntry($scope.diaryEntry);
    };

    // add any other shared functionality here.
}])

module.controller('Diary.AddDiaryController', function ($scope, $controller) {
    // instantiate base controller
    $controller('Diary.BaseAddEditController', { $scope: $scope });
}])

module.controller('Diary.EditDiaryController', function ($scope, $routeParams, DiaryService, $controller) {
    // instantiate base controller
    $controller('Diary.BaseAddEditController', { $scope: $scope });

    DiaryService.GetDiaryEntry($routeParams.id).success(function (data) {
        $scope.diaryEntry = data;
    });
}]);


답변

서비스를 주입하여 서비스를 생성하고 모든 컨트롤러에서 해당 동작을 상속 할 수 있습니다.

app.service("reusableCode", function() {

    var reusableCode = {};

    reusableCode.commonMethod = function() {
        alert('Hello, World!');
    };

    return reusableCode;
});

그런 다음 컨트롤러에서 위의 재사용 가능한 코드 서비스에서 확장하려고합니다.

app.controller('MainCtrl', function($scope, reusableCode) {

    angular.extend($scope, reusableCode);

    // now you can access all the properties of reusableCode in this $scope
    $scope.commonMethod()

});

데모 플 런커 : http://plnkr.co/edit/EQtj6I0X08xprE8D0n5b?p=preview


답변

다음과 같이 시도해 볼 수 있습니다 (테스트하지 않았습니다).

function baseController(callback){
    return function($scope){
        $scope.baseMethod = function(){
            console.log('base method');
        }
        callback.apply(this, arguments);
    }
}

app.controller('childController', baseController(function(){

}));