AngularJS
controllers
Sök…
Syntax
- <htmlElement ng-controller = "controllerName"> ... </htmlElement>
- <script> app.controller ('controllerName', controllerFunction); </ Script>
Din första kontroller
En styrenhet är en grundstruktur som används i Angular för att bevara omfattningen och hantera vissa åtgärder på en sida. Varje styrenhet är kopplad till en HTML-vy.
Nedan är en grundläggande pannplatta för en vinkelapp:
<!DOCTYPE html>
<html lang="en" ng-app='MyFirstApp'>
<head>
<title>My First App</title>
<!-- angular source -->
<script src="https://code.angularjs.org/1.5.3/angular.min.js"></script>
<!-- Your custom controller code -->
<script src="js/controllers.js"></script>
</head>
<body>
<div ng-controller="MyController as mc">
<h1>{{ mc.title }}</h1>
<p>{{ mc.description }}</p>
<button ng-click="mc.clicked()">
Click Me!
</button>
</div>
</body>
</html>
Det finns några saker att notera här:
<html ng-app='MyFirstApp'>
Om du ställer in appnamnet med ng-app
kan du komma åt applikationen i en extern Javascript-fil som kommer att behandlas nedan.
<script src="js/controllers.js"></script>
Vi behöver en Javascript-fil där du definierar dina kontroller och deras handlingar / data.
<div ng-controller="MyController as mc">
Attributet ng-controller
ställer in regulatorn för det DOM-elementet och alla element som är barn (rekursivt) under det.
Du kan ha flera av samma styrenhet (i detta fall MyController
) genom att säga ... as mc
, ger vi den här instansen av regulatorn ett alias.
<h1>{{ mc.title }}</h1>
Noteringen {{ ... }}
är ett vinkeluttryck. I detta fall kommer detta att ställa in den inre texten för det <h1>
-elementet till vad värdet av mc.title
är.
Obs: Angular använder databindning på två sätt, vilket innebär att oavsett hur du uppdaterar mc.title
värdet, kommer det att återspeglas i både styrenheten och sidan.
Observera också att vinkeluttryck inte behöver referera till en kontroller. Ett vinkeluttryck kan vara så enkelt som {{ 1 + 2 }}
eller {{ "Hello " + "World" }}
.
<button ng-click="mc.clicked()">
ng-click
är ett vinkeldirektiv som i detta fall binder klickhändelsen för knappen för att trigga den clicked()
-funktionen för MyController
instansen.
Med dessa saker i åtanke, låt oss skriva en implementering av MyController
controller. Med exemplet ovan skulle du skriva den här koden i js/controller.js
.
Först måste du instansera Angular-appen i ditt Javascript.
var app = angular.module("MyFirstApp", []);
Observera att namnet vi skickar här är detsamma som namnet du anger i din HTML med ng-app
direktivet.
Nu när vi har app-objektet kan vi använda det för att skapa kontroller.
app.controller('MyController', function(){
var ctrl = this;
ctrl.title = "My First Angular App";
ctrl.description = "This is my first Angular app!";
ctrl.clicked = function(){
alert("MyController.clicked()");
};
});
Obs: För allt som vi vill vara en del av controllerinstansen använder vi det this
nyckelordet.
Detta är allt som krävs för att bygga en enkel styrenhet.
Skapa kontroller
angular
.module('app')
.controller('SampleController', SampleController)
SampleController.$inject = ['$log', '$scope'];
function SampleController($log, $scope){
$log.debug('*****SampleController******');
/* Your code below */
}
Obs! Injektionen .$inject
att se till att dina beroenden inte blir förvrängda efter minifiering. Se också till att det är i ordning med den namngivna funktionen.
Skapa kontroller, minifiering säker
Det finns ett par olika sätt att skydda din controller skapande från minifiering.
Den första kallas inline array-kommentarer. Det ser ut enligt följande:
var app = angular.module('app');
app.controller('sampleController', ['$scope', '$http', function(a, b){
//logic here
}]);
Den andra parametern i kontrollmetoden kan acceptera en rad beroenden. Som ni ser har jag definierat $scope
och $http
som ska motsvara parametrarna för controller-funktionen där a
kommer att vara $scope
och b
skulle vara $http
. Observera att det sista objektet i matrisen bör vara din kontrollfunktion.
Det andra alternativet är att använda egenskapen $inject
. Det ser ut enligt följande:
var app = angular.module('app');
app.controller('sampleController', sampleController);
sampleController.$inject = ['$scope', '$http'];
function sampleController(a, b) {
//logic here
}
Detta gör samma sak som inline array-kommentarer men ger en annan styling för de som föredrar ett alternativ framför det andra.
Ordningen på injicerade beroenden är viktig
När du injicerar beroenden med hjälp av matrisformuläret, se till att listan med beroenden matchar dess motsvarande lista över argument som skickas till kontrollfunktionen.
Observera att i följande exempel är $scope
och $http
omvända. Detta kommer att orsaka problem i koden.
// Intentional Bug: injected dependencies are reversed which will cause a problem
app.controller('sampleController', ['$scope', '$http',function($http, $scope) {
$http.get('sample.json');
}]);
Använda ControllerAs i Angular JS
I Angular $scope
är limet mellan Controller och View som hjälper till med alla våra databindande behov. Controller Som är ett annat sätt att binda kontroller och visa och rekommenderas mest att använda. I grund och botten är detta de två controllerkonstruktionerna i Angular (dvs $ scope och Controller As).
Olika sätt att använda Controller As are -
controllerAs Visa syntax
<div ng-controller="CustomerController as customer">
{{ customer.name }}
</div>
controllerAs Controller Syntax
function CustomerController() {
this.name = {};
this.sendMessage = function() { };
}
controllerAs med vm
function CustomerController() {
/*jshint validthis: true */
var vm = this;
vm.name = {};
vm.sendMessage = function() { };
}
controllerAs
är syntaktiskt socker över $scope
. Du kan fortfarande binda till View och fortfarande komma åt $scope
metoder. Att använda controllerAs
är en av de bästa metoderna som föreslås av vinkelkärnan. Det finns många skäl till detta, få av dem är -
$scope
exponerar medlemmarna från kontrollenheten för vyn via ett mellanhandobjekt. Genom att ställa inthis.*
vi exponera precis vad vi vill exponera från regulatorn till vyn. Den följer också det vanliga JavaScript-sättet att använda detta.med
controllerAs
syntax, har vi mer läsbar kod och föräldraegenskapen kan nås med aliasnamnet på överordnad kontrollenhet istället för att använda$parent
syntaxen.Det främjar användningen av bindning till ett "prickat" objekt i vyn (t.ex. kund.namn istället för namn), vilket är mer kontextuellt, lättare att läsa och undviker alla referensproblem som kan uppstå utan att "prickas".
Hjälper till att undvika att använda
$parent
samtal i Visningar med kapslade kontroller.Använd en fångstvariabel för detta när du använder
controllerAs
syntax. Välj ett konsekvent variabelnamn somvm
, som står för ViewModel. Eftersomthis
nyckelord är kontextuellt och när det används i en funktion inuti en controller kan det ändra sammanhanget. Att fånga sammanhanget för detta undviker att stöta på problemet.
OBS: med hjälp av controllerAs
syntax läggs till nuvarande omfattningsreferens till aktuell controller, så det finns som fält
<div ng-controller="Controller as vm>...</div>
vm
är tillgängligt som $scope.vm
.
Skapa minifieringssäkra vinkelreglage
För att skapa minification säkra vinkel controllers, kommer du ändra controller
funktionsparametrarna.
Det andra argumentet i module.controller
funktionen ska skickas över en matris , där den sista parametern är styrfunktionen , och varje parameter innan det är namnet på varje injicerat värde.
Detta skiljer sig från det normala paradigmet; som tar kontrollfunktionen med de injicerade argumenten.
Given:
var app = angular.module('myApp');
Styrenheten ska se ut så här:
app.controller('ctrlInject',
[
/* Injected Parameters */
'$Injectable1',
'$Injectable2',
/* Controller Function */
function($injectable1Instance, $injectable2Instance) {
/* Controller Content */
}
]
);
Obs: Namnen på injicerade parametrar krävs inte för att matcha, men de kommer att vara bundna i ordning.
Detta kommer att minifiera till något liknande det här:
var a=angular.module('myApp');a.controller('ctrlInject',['$Injectable1','$Injectable2',function(b,c){/* Controller Content */}]);
Minifieringsprocessen kommer att ersätta varje instans av app
med a
, varje instans av $Injectable1Instance
med b
och varje instans av $Injectable2Instance
med c
.
Kapslade kontroller
Häckningskontrollanter kedjar också $scope
. Att ändra en $scope
variabel i den kapslade controller ändrar samma $scope
variabel i överordnade controller.
.controller('parentController', function ($scope) {
$scope.parentVariable = "I'm the parent";
});
.controller('childController', function ($scope) {
$scope.childVariable = "I'm the child";
$scope.childFunction = function () {
$scope.parentVariable = "I'm overriding you";
};
});
Låt oss nu försöka hantera båda, kapslade.
<body ng-controller="parentController">
What controller am I? {{parentVariable}}
<div ng-controller="childController">
What controller am I? {{childVariable}}
<button ng-click="childFunction()"> Click me to override! </button>
</div>
</body>
Häckningskontrollanter kan ha fördelar, men en sak måste komma ihåg när du gör det. Att ringa ngController
direktivet skapar en ny instans av regulatorn - vilket ofta kan skapa förvirring och oväntade resultat.