2016-07-08 2 views
0

구조가 매우 유사한 여러 패널로 구성된 페이지가 있습니다. 그들은 각각 하나의 컨트롤러를 사용합니다. 그러나 그들의 유사성에 난 컨트롤러 기능과 같이 재사용 :컨트롤러 기능 다시 사용하기 + 확장하기

function panelController($scope) { 
... 
} 
angular.module('myApp.controllers') 
    .controller('panel1Controller', panelController); 
angular.module('myApp.controllers') 
    .controller('panel2Controller', panelController); 

그 결과에 Panel1 및 panel2 자신 만의 독특한 범위를 가지고 있지만 뷰에 바인딩 할 수있는 측면에서 동일 보일 것입니다.

그러나 이제는 panel3에 대해 동일한 패턴을 사용하지만 약간의 확장을 사용하려고합니다. 즉, panel3에 대해서만 $ 범위에 포함시키고 자하는 항목이 있습니다. 그래서 이상적으로 다음과 같이 할 수 있습니다.

function panel3ControllerExtension($scope) { 
    $scope.panel3Field = "I must only live in panel3"; 
} 
angular.module('myApp.controllers') 
    .controller('panel3Controller', panelController, panel3ControllerExtension); 

하지만 그건 불가능합니다. 이것에 대한 좋은 패턴이 있습니까?


편집 : 마찬가지의 패널은 그들이 $ 범위에 포함하는 기대에서 유사하다. 특히 범위에는 고객 개체가 포함될 것으로 기대됩니다. 그래서 예. panel1은 $ scope.customer.name에 바인드하고 panel2는 $ scope.customer.phone에 바인드합니다. ... 그래서 그들은 다르게 보이고 다르게 행동하기 때문에 나는 그들의 지시를하는 것이 갈 길이라고 생각하지 않습니다. 틀 렸으면 고쳐줘.

+2

코드의 재사용 가능한 부분에 서비스를 사용해보십시오. –

답변

1

각도의 컨트롤러는 효과적으로 생성자로 사용됩니다. 따라서 Javascript의 "상속"규칙이 적용됩니다. 확장을위한 몇 가지 방법 :

  1. apply/call "기본"기능 :

    function panel3Controller($scope) { 
        // add the functionality of `panelController` to this scope 
        // in OO terms this can be thought of as calling the `super` constructor 
        panelController.call(this, $scope); 
        // add panel3 specific functionality 
        $scope.panel3SpecificThing = "..."; 
    } 
    // just register the new controller 
    angular.module('myApp.controllers') 
        .controller('panel3Controller', panel3Controller); 
    

    이 방법은 아마 당신은 당신의 코드에 최소한의 수정을 원하는 걸 얻을 것이다.

  2. JS 상속 사용 : 컨트롤러를 JS "클래스"로 만들고 하위 컨트롤러가 프로토 타입 적으로 상속하도록하십시오. 당신이 ES2015을 사용하는 경우

    function PanelController($scope) { 
        this.$scope = $scope; 
        this.something = '...'; 
    } 
    
    PanelController.prototype.someMethod = function() { 
        ... 
    } 
    
    function Panel3Controller($scope) { 
        PanelController.call(this, $scope); 
        this.somethingElse = '...'; 
    } 
    Panel3Controller.prototype = new PanelController(); 
    Panel3Controller.prototype.constructor = Panel3Controller; 
    
    Panel3Controller.prototype.panel3SpecificMehod = function() { 
        ... 
    }; 
    

    , 위의 단순화 할 수있다 :

    class PanelController { 
        constructor($scope) { 
         ... 
        } 
        ... 
    } 
    
    class Panel3Controller extends PanelController { 
        constructor($scope) { 
         super($scope); 
         ... 
        } 
        ... 
    } 
    

    다시 말하지만, 당신이 혼자 새 컨트롤러를 등록 또한 controller as 구문과 연동 해이를 사용할 수 있습니다 :

    angular.module('myApp.controllers') 
        .controller('panel3Controller', Panel3Controller); 
    

    다음과 같이 특성 및 방법은, 제어부에 배치하는 경우는 HTML에서 controller as 구문, 즉 사용 모듈 시스템을 적절하게 사용하면이 패턴이 유용합니다.

  3. 컨트롤러의 정확한 기능에 따라, 주석에서 지적한대로 하나 이상의 서비스에서 컨트롤러의 기능을 추출 할 수 있습니다. 그런 다음 컨트롤러는 이러한 서비스를위한 씬 래퍼가됩니다. 다시 말하지만 이것이 좋은 아이디어인지 아닌지는 컨트롤러의 정확한 기능에 달려 있습니다.지침에 관해서는

: 그들은 항상 갈 :) 그리고 당신은 ng-controller 함께 사용하는 대신 지침의 컨트롤러로 코드를 재사용 할 수있는 방법입니다. 템플릿이 다른 두 개의 지시문 (예 : customer.namecustomer.phone 바인딩)과 동일한 컨트롤러를 사용할 수도 있습니다.

관련 문제