2013-03-25 3 views
26

Ich habe einen Controller definiert, und wenden Sie es auf 2 Ansichten mit kleinen Unterschieden an.Wie kann ein Controller für zwei verschiedene Ansichten wiederverwendet werden?

Angular Code:

app.controller('MyCtrl', function($scope) { 
    $scope.canSave = false; 
    $scope.demo = { 
     files : [{ 
     filename: 'aaa.html', 
     source: '<div>aaa</div>' 
     }, { 
     filename: 'bbb.html', 
     source: '<div>bbb</div>' 
     }] 
    } 
    $scope.newFile = function(file) { 
     $scope.demo.files.push(file); 
    } 
    $scope.$watch("demo.files", function(val) { 
     $scope.canSave = true; 
    }, true); 
}); 

Ansicht 1:

<div ng-controller="MyCtrl"></div> 

Ansicht 2:

<div ng-controller="MyCtrl"></div> 

Das Codebeispiel ist sehr einfach, aber es gibt eine Menge Code und Logik in meinem echten Projekt.

Die Ansicht 1 und 2 haben fast die gleichen Funktionen, nur mit ein paar Unterschieden, aber ich muss etwas Code für jeden von ihnen in der Steuerung schreiben.

Ich möchte nicht 2 verschiedene Controller für sie erstellen, weil sie die meisten der gleichen Logik haben. Ich möchte die Logik nicht in einen Dienst verschieben, um ihn zwischen den beiden Controllern zu teilen, weil die Logik nicht so üblich ist, um ein Dienst zu sein.

Gibt es einen anderen Weg, es zu tun?

+0

Also einfach alles, was man für beide Ansichten in diesem einen Controller benötigen setzen und Sie sind bereit zu gehen ... – finishingmove

+1

Die Logik muss nicht immer und überall verwendet werden, sich zu bewegen es zu einem Dienst. Ein Service muss der Ort sein, an dem der Großteil Ihrer Logik gehen sollte, egal ob er geteilt wurde oder nicht. – ganaraj

Antwort

16

Unter den gegebenen Bedingungen kann ich etwas tun wie

function MyCommonCtrl(type){ 
    return function($scope, $http) { 
     $scope.x = 5; 

     if(type = 't1'){ 
      $scope.domore = function(){ 
      } 
     } 

     .... 
     .... 
    } 
} 

angular.module('ng').controller('Type1Ctrl', ['$scope', '$http', MyCommonCtrl('t1')]); 
angular.module('ng').controller('Type2Ctrl', ['$scope', '$http', MyCommonCtrl('t2')]); 

Dann

<div ng-controller="Type1Ctrl"></div> 

und

<div ng-controller="Type2Ctrl"></div> 
+1

Für mich sieht das eher nach einem Hack aus als nach einer Lösung. Also -1. Ich mag die saubere Lösung mit Vererbung von @AXZR empfohlen Weg besser. –

+1

Das ist in der Tat eine schlechte Lösung, denke ich. – fdomig

+3

Ich mag diese Lösung - eine wahre Funktion-Schlinge traditionellen Javascript-Ansatz, mit wenigen, wenn keine Nachteile. Vollständig testbar, flexibel und einfach zu verstehen. Vererbung ist viel wahrscheinlicher, Ihnen Kopfschmerzen auf der Straße wegen seiner weniger offensichtlichen Arbeiten und addierter Komplexität w/r zu eigenen und vererbten Eigenschaften zu geben. –

6

Ich weiß nicht, Ihr spezifisches Set-up, aber Ihre 2 Controller könnten von einem gemeinsamen Vorfahren erben.

Type1Ctrl.prototype = new MyCtrl(); 
Type1Ctrl.prototype.constructor = Type1Ctrl; 

function Type1Ctrl() { 
    // constructor stuff goes here 
} 

Type1Ctrl.prototype.setScope = function() { 
    // setScope 
}; 

Type2Ctrl.prototype = new MyCtrl(); 
Type2Ctrl.prototype.constructor = Type2Ctrl; 

function Type2Ctrl() { 
    // constructor stuff goes here 
} 

Type2Ctrl.prototype.setScope = function() { 
    // setScope 
}; 
+0

Ich habe nie Controller wie diese geschrieben, können Sie mir mehr Informationen darüber geben? – Freewind

+0

@Freewind: sicher. Könnten Sie ein wenig mehr Logik von Ihren vorhandenen Controllern veröffentlichen und ich kann Ihnen helfen, sie so zu gestalten, dass sie die Vererbung verwenden? Entweder das oder einfach etwas über Vererbung in Javascript lesen. – axzr

+0

Danke @axzr, siehe meine aktualisierte Frage bitte. – Freewind

3

Ich konfrontiert auch ähnliche Problem und Umfang Vererbung mein Problem gelöst. Ich wollte einen Controller "wiederverwenden", um gemeinsamen Zustand/Modell ($ Scope) und Funktionalität (Controller-Funktionen an $ Scope) zu vererben Wie in der "Scope Inheritance Example" beschrieben, schließe ich übergeordneten Controller an ein äußeres DOM-Element und Kind-Controller an die innere . Umfang und Funktionen des übergeordneten Controllers "fusionieren" nahtlos in den untergeordneten.

+0

Dies wird in Angular.JS 1.3+ als fehlerhaft angesehen. – Thomas

3

Hier ist eine weitere Option. Etwas von this blog post

app.factory('ParentCtrl',function(){ 
    $scope.parentVar = 'I am from the parent' 
    }; 
}); 

app.controller('ChildCtrl', function($scope, $injector, ParentCtrl) { 
    $injector.invoke(ParentCtrl, this, {$scope: $scope}); 
}); 
modifizierte

here is a plunker

+0

Fehlerhafter Link zum Blogeintrag. –