Zoeken…


Opmerkingen

Angular gebruikt een boom met scopes om de logica (van controllers, richtlijnen, enz.) Aan de weergave te binden en zijn het primaire mechanisme achter de detectie van wijzigingen in AngularJS. Een meer gedetailleerde referentie voor scopes is te vinden op docs.angularjs.org

De root van de boom is toegankelijk als via injecteerbare service $ rootScope . Alle kind $ scopes erven de methoden en eigenschappen van hun bovenliggende $ scope, waardoor kinderen toegang hebben tot methoden zonder het gebruik van Angular Services.

Basisvoorbeeld van overname van $ 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>

In dit voorbeeld creëert de ng-repeat-richtlijn een nieuw toepassingsgebied voor elk van de nieuw gecreëerde kinderen.

Deze gemaakte scopes zijn kinderen van hun bovenliggende scope (in dit geval de scope gemaakt door myController), en daarom erven ze alle bijbehorende proporties, zoals person.

Vermijd erfelijke waarden

Als u in javascript een niet- primitieve waarde toewijst (zoals Object, Array, Function en nog veel meer), wordt een verwijzing (een adres in het geheugen) naar de toegewezen waarde bewaard.

Door een primitieve waarde (String, Number, Boolean of Symbol) toe te wijzen aan twee verschillende variabelen en er één te wijzigen, worden beide niet gewijzigd:

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

Maar met een niet-primitieve waarde, aangezien beide variabelen zijn eenvoudig houden verwijzingen naar een object, het veranderen van een variabele de andere veranderen:

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

In het hoekige, wanneer een bereik wordt gemaakt, krijgt het alle eigenschappen van de bovenliggende toegewezen. Veranderende eigenschappen achteraf hebben echter alleen invloed op de bovenliggende scope als het een niet-primitieve waarde is:

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>

Onthoud: in Angular scopes kunnen op vele manieren worden gemaakt (zoals ingebouwde of aangepaste richtlijnen, of de $scope.$new() functie), en het bijhouden van de scope tree is waarschijnlijk onmogelijk.

Als u alleen niet-primitieve waarden als scope-eigenschappen gebruikt, blijft u aan de veilige kant (tenzij u een eigenschap nodig hebt om niet te erven, of andere gevallen waarin u op de hoogte bent van scope-overerving).

Een functie beschikbaar in de hele app

Wees voorzichtig, deze aanpak kan worden beschouwd als een slecht ontwerp voor hoekige apps, omdat het vereist dat programmeurs zowel onthouden waar functies in de scoopboom worden geplaatst als op de hoogte zijn van scoopovererving. In veel gevallen verdient het de voorkeur om een service te injecteren ( Angular Practice - Scope inheritance versus Injection) .

Dit voorbeeld laat alleen zien hoe scope-overerving kan worden gebruikt voor onze behoeften, en hoe u hiervan kunt profiteren, en niet de best practices voor het ontwerpen van een volledige app.

In sommige gevallen kunnen we profiteren van de overerving van een bereik en een functie instellen als een eigenschap van de rootScope. Op deze manier nemen alle scopes in de app (behalve geïsoleerde scopes) deze functie over en kan deze overal in de app worden aangeroepen.

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>

Aangepaste $ scope-evenementen maken

Net als normale HTML-elementen is het mogelijk voor $ scopes om hun eigen evenementen te hebben. Op $ scope-evenementen kan op de volgende manier worden geabonneerd:

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

Als u een gebeurtenislistener wilt afmelden, retourneert de functie $ on een niet-bindende functie. Om door te gaan met het bovenstaande voorbeeld:

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

Er zijn twee manieren om uw eigen aangepaste $ scope-gebeurtenis $ broadcast en $ emit te activeren. Gebruik $ emit om de ouder (s) op de hoogte te stellen van een scope van een specifieke gebeurtenis

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

Het bovenstaande voorbeeld activeert alle gebeurtenislisteners voor my-event in het bovenliggende bereik en gaat verder in de scoopboom naar $ rootScope tenzij een luisteraar stopPropagation voor het evenement stopPropagation . Alleen gebeurtenissen die worden geactiveerd met $ emit mogen stopPropagation

Het omgekeerde van $ emit is $ broadcast , wat alle eventlisteners op alle onderliggende scopes in de scoopstructuur activeert die kinderen zijn van de scope die $ broadcast wordt genoemd .

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

Evenementen die worden geactiveerd met $ broadcast kunnen niet worden geannuleerd.

$ Scope-functies gebruiken

Hoewel het declareren van een functie in de $ rootscope zijn voordelen heeft, kunnen we ook een $ scope-functie declareren voor elk deel van de code dat door de $ scope-service wordt geïnjecteerd. Controller bijvoorbeeld.

controleur

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

Nu kunt u uw functie vanaf de controller oproepen met:

$scope.myfunction();

Of via HTML die zich onder die specifieke controller bevindt:

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

Richtlijn

Een hoekrichtlijn is een andere plaats waar u uw scope kunt gebruiken:

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

En in uw HTML-code onder dezelfde controller:

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

Natuurlijk kunt u ngMouseover voor hetzelfde gebruiken, maar het bijzondere van richtlijnen is dat u ze naar wens kunt aanpassen. En nu weet je hoe je je $ scope-functies erin kunt gebruiken, wees creatief!

Hoe kunt u de reikwijdte van een richtlijn beperken en waarom zou u dit doen?

Scope wordt gebruikt als de "lijm" die we gebruiken om te communiceren tussen de bovenliggende controller, de richtlijn en de richtlijnsjabloon. Telkens wanneer de AngularJS-toepassing wordt opgestart, wordt een rootScope-object gemaakt. Elke scope gemaakt door controllers, richtlijnen en services is prototypisch overgenomen van rootScope.

Ja, we kunnen de reikwijdte van een richtlijn beperken. We kunnen dit doen door een geïsoleerde reikwijdte voor richtlijnen te creëren.

Er zijn 3 soorten richtlijnbereiken:

  1. Scope: False (richtlijn gebruikt het bovenliggende bereik)
  2. Scope: True (richtlijn krijgt een nieuwe scope)
  3. Scope: {} (richtlijn krijgt een nieuwe geïsoleerde scope)

Richtlijnen met het nieuwe geïsoleerde bereik: wanneer we een nieuw geïsoleerd bereik maken, wordt dit niet overgenomen van het bovenliggende bereik. Deze nieuwe scope wordt geïsoleerde scope genoemd omdat deze volledig los staat van de bovenliggende scope. Waarom? moeten we geïsoleerde scope gebruiken: we moeten geïsoleerde scope gebruiken wanneer we een aangepaste richtlijn willen maken, omdat deze ervoor zorgt dat onze richtlijn generiek is en overal in de toepassing wordt geplaatst. Het toepassingsgebied van de ouders gaat het toepassingsgebied van de richtlijn niet verstoren.

Voorbeeld van geïsoleerde scope:

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'/>"
    };
});

Er zijn 3 soorten voorvoegsels AngularJS biedt geïsoleerde reikwijdte, dit zijn:

  1. "@" (Bindend voor tekst / bindend in één richting)
  2. "=" (Directe modelbinding / tweewegbinding)
  3. "&" (Gedragsbinding / methodebinding)

Al deze voorvoegsels ontvangen gegevens van de kenmerken van het richtlijnelement, zoals:

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


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow