6

Ich versuche, einige von winkelförmigen Stangen Best Practices auf der Website Google-Styleguide definiert zu verwenden: https://google-styleguide.googlecode.com/svn/trunk/angularjs-google-style.htmlAngularJS Best Practices - Styleguide

Aber im Moment habe ich mit einigen Fragen bin zu kämpfen. Bevor ich diesen Styleguide verwendet habe, hatte ich die Variable $scope verfügbar, um zum Beispiel eine $watch auf einer Variablen zu machen.

app.controller('myController',['$scope', function($scope) { 
    $scope.$watch('myVariable', function(val) { 
     alert("I'm changed"); 
    }); 
}]); 

Jetzt mit meinem neuen Ansatz weiß ich nicht, wie man damit umgeht? Sollte ich noch spritzen $scope? Weil ich nicht $scope spritzen muss, wenn ich $watch nicht verwende.

function myController($scope) { 
    var vm = this; 

    vm.myVariable = "aVariable"; 
    vm.$watch('vm.myVariable', function(val) { 
     // error because $watch is undefined 
    }); 

    //$scope.$watch - works 
} 

app.controller('myController',['$scope', myController]); 

Der Styleguide empfiehlt auch, Prototypen zu verwenden. Aber was, wenn ich eine Dienstleistung einspritzen müsste? Was ist der beste Ansatz, um einen Service in Ihrem Prototyp zu verwenden?

function myController(MyService) { 
    var vm = this; 

    vm.myService = MyService; 
} 

myController.prototype.callService = function() { 
    var vm = this; 

    vm.myService.doSomething(); 
} 

Ist das korrekt? Oder vermisse ich etwas, gibt es einen Ort, wo ich mehr Informationen über diese Art der eckigen Programmierung finden kann?

Meiner Meinung nach fühlt es sich mehr wie natürliches Javascript an und ich möchte diese Art der Organisation meiner AngularJS-Apps verwenden.

Vielen Dank im Voraus

aktualisieren

Für den 'Dienst' Problem, das ich war etwas zu denken wie folgt:

function MyBaseController(AService, BService, CService) { 
    this.aService = AService; 
    this.bService = BService; 
    this.cService = CService; 
} 

function myController() { 
    var vm = this; 
    MyBaseController.apply(vm, arguments); 
} 

myController.prototype.doSomething() { 
    var vm = this; 
    this.aService.somethingElse(); 
} 

Aber dieses Recht imo nicht fühlen ..

+0

Große Frage! Für Ihre Frage zu der $ Uhr frage ich mich, ob der Styleguide versucht, $ watch in einem Controller zu nennen, da sie "Controller sind Klassen" angeben. Da Sie wissen, wann sich Daten innerhalb eines Controllers ändern, könnte es sein, dass Ihre "$ watch" ausgeführt wird, wenn eine bestimmte Methode innerhalb des Controllers aufgerufen wird? – Pete

+0

Eigentlich möchte ich eine '$ watch' für eine Variable machen, die innerhalb einer Direktive geändert wird. Ich denke, es würde kein Problem geben, wenn Sie eine Variable in einer Methode ändern. Der Bereich, nennen wir es, wird sowieso aktualisiert. – Dieterg

+1

In einer Direktive können Sie über Link, Compile und Controller auf den Bereich zugreifen, sodass in diesen Fällen auf $ watch zugegriffen werden kann. – Pete

Antwort

7

Es ist durchaus zulässig, $ scope zu injizieren, um Zugriff auf Dinge wie $ watch zu bekommen, selbst wenn Sie den "controller as" -Sy benutzen NTAX. Zum Beispiel:

JS

var MyController = function($scope) { 
    $scope.$watch('ctrl.someVar' function() { 
     ... 
    }); 

    this.someVar = 123; 
} 

MyController.$inject = ['$scope']; 

HTML

<div ng-controller="MyController as ctrl"> 
    .... 
</div> 

Das erste Beispiel, das Sie von Einspritzen eines Service gab in einen Controller gut ist. Für das Vererbungsbeispiel würde ich so etwas tun.

var BaseController = function(AService, BService) { 
    this.aService = AService; 
    this.bService = BService; 
} 

BaseController.prototype.doSomethingWithAAndB = function() { 
    ... 
} 

var MyController = function(AService, BService, CService) { 
    BaseController.call(this, AService, BService); 

    this.cService = CService; 
} 

MyController.$inject = ['AService', 'BService', 'CService']; 

//Note: you'll need to add a polyfill for Object.create if you want to support ES3. 
MyController.prototype = Object.create(BaseController.prototype); 

Wenn Sie es zu umständlich ist es, alle Parameter in der untergeordneten Steuerung angeben können Sie immer $injector nur injizieren und dass die Steuerung an Ihrer Basis verzichten.

+0

Bei Ihrem Vererbungsbeispiel könnte es sich lohnen, den Prototypenkonstruktor auch 'MyControlleer.prototype.constructor = MyController' zu setzen. Siehe http://stackoverflow.com/questions/8453887/why-is-it-necessary-to-set-the-prototype-constructor/8454111#8454111 – Beyers

1

@rob Antwort ist korrekt. Es gibt durchaus stichhaltige Gründe, immer noch $scope in Ihre Controller injiziert zu haben, $watch$on$emit$broadcast um nur einige zu nennen. Sicher, Sie können in einigen Fällen mit dieser Anforderung durch Richtlinien oder Dienste davonkommen, aber es ist nicht immer die Zeit oder Komplexität wert.

Ich habe die controller as Syntax a go, aber festgestellt, dass in den meisten meiner Anwendungsfälle hatte ich noch eine Abhängigkeit von $scope in meinen Controllern.Ich mochte diese und so landete ich mit folgenden Konvention bis:

var MyController = function($scope) { 
    $scope.vm = {}; 
    var vm = $scope.vm; 

    vm.propA = 1; 
    vm.propB = 2; 
    vm.funcA = function(){}; 

    $scope.$watch('vm.propA' function() { 
    }); 
} 

So ist es den ‚alte Schule‘ Ansatz verwendet, aber mit einer neuen Schule fühlen. Alles in der Ansicht hängt von vm.