2016-07-08 13 views
0

Ich habe eine Seite, die aus mehreren Panels besteht, die in ihrer Struktur sehr ähnlich sind. Sie verwenden jeweils einen Controller. Aber aufgrund ihrer Ähnlichkeit wiederzuverwenden i die Controller-Funktion wie folgt:Wiederverwendung von Controller-Funktion + Erweiterung

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

Das Ergebnis ist, dass panel1 und panel2 haben ihre jeweils eigene Bereiche, aber das gleiche in Bezug auf die schauen, was die Sicht zu binden.

Jetzt aber bin ich an einem Punkt, wo ich das gleiche Muster für Panel3 verwenden möchte, aber mit einer leichten Erweiterung. Das heißt, ich möchte etwas nur in den $ scope für Panel3 einfügen. Also im Idealfall würde ich gerne so etwas machen können:

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

Aber das ist nicht möglich. Gibt es dafür irgendwelche guten Muster?


Edit: Die ähnlichen Platten ähnlich sind nur in dem, was sie den $ Umfang enthalten erwarten. Insbesondere erwarten Sie, dass der Bereich ein Kundenobjekt enthält. So z.B. panel1 bindet an $ scope.customer.name und panel2 an $ scope.customer.phone. ... Da sie anders aussehen und sich anders verhalten, glaube ich nicht, dass eine Anweisung von ihnen der richtige Weg ist. Korrigiere mich, wenn ich falsch liege.

+2

Sie sollten versuchen, einen Dienst für wiederverwendbare Teile Ihres Codes zu verwenden. –

Antwort

1

Controller in Angular werden effektiv als Konstruktoren verwendet. Also gelten die Regeln für "Vererbung" in Javascript für sie. Einige Methoden für die Erweiterung:

  1. apply/call die „Basis“ Funktion:

    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); 
    

    Diese Methode werden Sie wahrscheinlich bekommen, was Sie mit den minimalen Änderungen an Ihrem Code möchten.

  2. Verwenden Sie JS-Vererbung: Machen Sie den Controller zu einer JS "Klasse" und lassen Sie den Kind-Controller prototypisch davon erben. Sie können auch diese in Verbindung mit der controller as Syntax verwenden möchten:

    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() { 
        ... 
    }; 
    

    Wenn Sie ES2015 verwenden, können die oben vereinfacht werden:

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

    Wieder Sie nur allein den neuen Controller registrieren:

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

    Wenn die Eigenschaften und Methoden in der Steuerung gesetzt werden, wie hier gezeigt, verwenden Sie die controller as Syntax, also im HTML:

    <div ng-controller="panel3Controller as p3ctrl"> 
        <span>{{ p3ctrl.somethingElse }}</span> 
    

    Wenn ein Modulsystem vorhanden ist, ist dieses Muster sehr nützlich.

  3. Abhängig von der genauen Funktionalität der Controller und, wie in einem Kommentar erwähnt, können Sie möglicherweise die Funktionalität der Controller in einem oder mehreren Diensten extrahieren. Dann werden die Controller dünne Wrapper für diese Dienste sein. Ob dies eine gute Idee ist oder nicht, hängt von der genauen Funktionalität der Steuerung (en) ab.

Bezüglich Richtlinien: Sie sind immer der Weg zu gehen :) Und Sie können Ihren Code wie die Steuerung der Richtlinie anstelle der Verwendung mit ng-controller wiederzuverwenden. Sie können sogar zwei Direktiven mit unterschiedlichen Vorlagen verwenden (z. B. die customer.name und customer.phone Bindung) und den gleichen Controller.