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 in this.* 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 som vm , som står för ViewModel. Eftersom this 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.



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow