Sök…


Anmärkningar

Angular använder ett träd av scopes för att binda logiken (från styrenheter, direktiv etc.) till vyn och är den primära mekanismen bakom förändringsdetektering i AngularJS. En mer detaljerad referens för omfattningar finns på docs.angularjs.org

Trädets rot är tillgänglig via en insprutningsbar tjänst $ rootScope . Alla barn $ -områden ärver metoderna och egenskaperna för deras förälder $ -omfång, vilket ger barn tillgång till metoder utan användning av Angular Services.

Grundläggande exempel på arv från $ scope

angular.module('app', [])
.controller('myController', ['$scope', function($scope){
    $scope.person = { name: 'John Doe' };
}]);

<div ng-app="app" ng-conroller="myController">
    <input ng-model="person.name" />
    <div ng-repeat="number in [0,1,2,3]">
        {{person.name}} {{number}}
    </div>
</div>

I det här exemplet skapar ng-repetitionsdirektivet ett nytt räckvidd för var och en av dess nyskapade barn.

Dessa skapade räckvidd är barn av deras föräldraområde (i detta fall omfattningen skapad av myController), och därför ärver de alla dess proportioner, till exempel person.

Undvik att ärva primitiva värden

Tilldela ett icke- primitivt värde (som Objekt, Array, Funktion och många fler) i javascript, en referens (en adress i minnet) till det tilldelade värdet.

Att tilldela ett primitivt värde (String, Number, Boolean eller Symbol) till två olika variabler och ändra en, kommer inte att ändra båda:

var x = 5;
var y = x;
y = 6;
console.log(y === x, x, y); //false, 5, 6

Men med en icke-primitivt värde, eftersom båda variablerna helt enkelt hålla referenser till samma objekt, ändra en variabel kommer att förändra andra:

var x = { name : 'John Doe' };
var y = x;
y.name = 'Jhon';
console.log(x.name === y.name, x.name, y.name); //true, John, John

I vinkel tilldelas det alla dess överordnade egenskaper när ett omfång skapas, men ändra egenskaper efteråt påverkar dock endast överordnade omfång om det är ett icke-primitivt värde:

angular.module('app', [])
.controller('myController', ['$scope', function($scope){
    $scope.person = { name: 'John Doe' }; //non-primitive
    $scope.name = 'Jhon Doe'; //primitive
}])
.controller('myController1', ['$scope', function($scope){}]);

<div ng-app="app" ng-controller="myController">
    binding to input works: {{person.name}}<br/>
    binding to input does not work: {{name}}<br/>
    <div ng-controller="myController1">
        <input ng-model="person.name" />
        <input ng-model="name" />
    </div>
</div>

Kom ihåg: i kantiga omfångar kan skapas på många sätt (till exempel inbyggda eller anpassade direktiv eller funktionen $scope.$new() ), och det är förmodligen omöjligt att hålla reda på omfattningsträdet.

Om du bara använder icke-primitiva värden som omfattningsegenskaper kommer du att hålla dig på den säkra sidan (såvida du inte behöver en egendom för att inte ärva, eller andra fall där du är medveten om omfattningarv).

En funktion som är tillgänglig i hela appen

Var försiktig, detta tillvägagångssätt kan betraktas som en dålig design för kantiga appar, eftersom det kräver att programmerare ska komma ihåg både var funktioner placeras i omfattningsträdet och att vara medvetna om omfattningsarv. I många fall skulle det vara att föredra att injicera en tjänst ( vinkelpraxis - med användning av omfattningsarv kontra injektion) .

Det här exemplet visar bara hur omfattningsarv kan användas för våra behov och hur du kan dra nytta av det och inte de bästa metoderna för att utforma en hel app.

I vissa fall kan vi dra nytta av omfattningsarv och ställa in en funktion som egenskap hos rootScope. Det här sättet - alla scopes i appen (med undantag för isolerade scopes) ärver den här funktionen, och den kan kallas var som helst i appen.

angular.module('app', [])
.run(['$rootScope', function($rootScope){
    var messages = []
    $rootScope.addMessage = function(msg){
        messages.push(msg);
    }
}]);

<div ng-app="app">
    <a ng-click="addMessage('hello world!')">it could be accsessed from here</a>
    <div ng-include="inner.html"></div>
</div>

inner.html:

<div>
    <button ng-click="addMessage('page')">and from here to!</button>
</div>

Skapa anpassade händelser för $ scope

Liksom vanliga HTML-element är det möjligt för $ scopes att ha sina egna händelser. Händelser för $ scope kan prenumereras på följande sätt:

 $scope.$on('my-event', function(event, args) {
    console.log(args); // { custom: 'data' }
});

Om du behöver avregistrera en händelse lyssnare, kommer $ on- funktionen att returnera en obegränsad funktion. För att fortsätta med ovanstående exempel:

var unregisterMyEvent = $scope.$on('my-event', function(event, args) {
    console.log(args); // { custom: 'data' }
    unregisterMyEvent();
});

Det finns två sätt att utlösa din egen anpassade $ scope-händelse $ broadcast och $ emit . Använd $ emit för att meddela föräldrarna om en räckvidd för en specifik händelse

$scope.$emit('my-event', { custom: 'data' }); 

Exemplet ovan utlöser alla händelselister för my-event på överordnade omfång och fortsätter uppåt-trädet till $ rootScope såvida inte en lyssnare kallar stopPropagation på händelsen. Endast händelser som utlöses med $ emit kan kalla stopPropagation

Det omvända av $ emit är $ -sändning , vilket utlöser alla händelser som lyssnar på alla barnomfattningar i omfångsträdet som är barn i omfattningen som kallas $ -sändning .

$scope.$broadcast('my-event', { custom: 'data' });

Händelser som utlöses med $ -sändning kan inte avbrytas.

Använda $ scope-funktioner

Samtidigt som det har fördelar att förklara en funktion i $ rootscope, kan vi också förklara en $ scope-funktion vilken som helst del av koden som injiceras av $ scope-tjänsten. Controller, till exempel.

Kontrollant

myApp.controller('myController', ['$scope', function($scope){
    $scope.myFunction = function () {
        alert("You are in myFunction!");
    };
}]);

Nu kan du ringa din funktion från regulatorn med hjälp av:

$scope.myfunction();

Eller via HTML som ligger under den specifika kontrollern:

<div ng-controller="myController">
    <button ng-click="myFunction()"> Click me! </button>
</div>

Direktiv

Ett vinkeldirektiv är en annan plats som du kan använda din räckvidd:

myApp.directive('triggerFunction', function() {
    return {
        scope: {
            triggerFunction: '&'
        },
        link: function(scope, element) {
            element.bind('mouseover', function() {
                scope.triggerFunction();
            });
        }
    };
});

Och i din HTML-kod under samma styrenhet:

<div ng-controller="myController">
    <button trigger-function="myFunction()"> Hover over me! </button>
</div>

Naturligtvis kan du använda ngMouseover för samma sak, men det som är speciellt med direktiv är att du kan anpassa dem som du vill. Och nu vet du hur du använder dina $ scope-funktioner inuti dem, var kreativ!

Hur kan du begränsa tillämpningsområdet för ett direktiv och varför skulle du göra det?

Räckvidd används som "limet" som vi använder för att kommunicera mellan överordnad kontrollenhet, direktivet och direktivsmallen. Närhelst AngularJS-programmet startas upp skapas ett rootScope-objekt. Varje räckvidd som skapas av kontrollörer, direktiv och tjänster ärvs prototypiskt från rootScope.

Ja, vi kan begränsa tillämpningsområdet för ett direktiv. Vi kan göra det genom att skapa ett isolerat utrymme för direktiv.

Det finns tre typer av direktiv:

  1. Räckvidd: Falsk (direktivet använder sitt överordnade tillämpningsområde)
  2. Räckvidd: Sann (direktivet får ett nytt tillämpningsområde)
  3. Räckvidd: {} (Direktivet får ett nytt isolerat tillämpningsområde)

Direktiv med det nya isolerade tillämpningsområdet: När vi skapar ett nytt isolerat tillämpningsområde kommer det inte att ärvas från moderområdet. Det nya räckvidden kallas Isolated scope eftersom det är helt fristående från sitt moderområde. Varför? ska vi använda isolerat omfattning: Vi bör använda isolerat omfattning när vi vill skapa ett anpassat direktiv eftersom det kommer att se till att vårt direktiv är generiskt och placerat var som helst i applikationen. Föräldrarnas tillämpningsområde kommer inte att störa direktivets tillämpningsområde.

Exempel på isolerat omfattning:

var app = angular.module("test",[]);

app.controller("Ctrl1",function($scope){
    $scope.name = "Prateek";
    $scope.reverseName = function(){
        $scope.name = $scope.name.split('').reverse().join('');
    };
});
app.directive("myDirective", function(){
    return {
        restrict: "EA",
        scope: {},
        template: "<div>Your name is : {{name}}</div>"+
        "Change your name : <input type='text' ng-model='name'/>"
    };
});

Det finns tre typer av prefix som AngularJS tillhandahåller för isolerat omfattning. Dessa är:

  1. "@" (Textbindande / enkelriktad bindning)
  2. "=" (Direktmodellbindning / tvåvägsbindning)
  3. "&" (Beteende / Metodbindning)

Alla dessa prefix får information från attributen för direktivet som:

<div my-directive 
  class="directive"
  name="{{name}}" 
  reverse="reverseName()" 
  color="color" >
</div>


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