Usługi $scope

bugajsky.pl 6 lat temu

W tym wpisie zajmiemy się omówieniem usług odpowiedzialnych za nasłuchiwanie zmian w obiekcie $scope. Omówione zostaną $watch(), $digest(), $apply(), dzięki którym mamy większą kontrolę nad zmianami w $scope().

Nie wszystkie elementy posiadają nasłuch. Spowodowane jest to zbyt długim czasem, potrzebnym do nasłuchu wszystkich elementów.

$watch()

Usługa ta służy do tworzenia nasłuchu zmian w konkretnym elemencie obiektu $scope. Kiedy zostaje wykryta zmiana w elemencie, wykonywana jest określona funkcja. Do wykrycia zmian wykorzystywany jest cykl $digest().

Przykładowe użycie usługi

$scope.$watch('name', function (newName, oldName) { console.log("Watch new: " + newName) console.log("Watch old: " + oldName) }

Pierwszy parametr $watch(), to nazwa elementu, zaś kolejny jest funkcją przyjmująca dwa parametry. Pierwszym parametrem funkcji zwrotnej jest nowa wartość odczytana z elementu, natomiast drugi parametr to poprzednia wartość.

$digest()

Możemy rozumieć to jako pętlę, która sprawdza czy nastąpiła zmiana w nasłuchiwanych elementach. Zakres elementów jaki jest sprawdzany to obecny $scope oraz jego potomkowie. Dyrektywy ng-model oraz ng-click automatycznie uruchamiają ten cykl. Poprawną praktyką jest nie używanie usługi $digest(), a wykorzystywanie $apply, który to wywołuje omawianą usługę.

$apply()

Podobnie jak wcześniej opisany $digest(), usługa ta odpowiada za sprawdzenie nasłuchiwanych elementów. Różnica jednak polega na tym, iż sprawdzane są wszystkie obiekty $scope. Wykorzystywana jest najczęściej przy tworzeniu rozbudowanych projektów oraz w przypadku łączenia z innymi frameworkami np. jQuery.

Przykładowe użycie usługi

$scope.showText = function () { setTimeout(function () { $scope.name = 'Hello World'; console.log("Apply: " + $scope.name); $scope.$apply() }, 5000); }

Gotowy kod aplikacji

<!DOCTYPE html> <html lang="pl" ng-app="app"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>AngularJS #3</title> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> </head> <body ng-controller="appCtrl"> <div> <h1>{{name}}</h1> <form role="form"> <div> <input type="text" ng-model="name"> </div> </form> </div> <script src="https://code.jquery.com/jquery-3.2.1.slim.js" integrity="sha256-tA8y0XqiwnpwmOIl3SGAcFl2RvxHjA8qp0+1uCGmRmg=" crossorigin="anonymous"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular.min.js"></script> <script> var app = angular.module("app", []); app.controller("appCtrl", function ($scope) { $scope.name = "Aplikacja 3"; $scope.$watch('name', function (newName, oldName) { console.log("Watch new: " + newName) console.log("Watch old: " + oldName) }) $scope.showText = function () { setTimeout(function () { $scope.name = 'Hello World'; console.log("Apply: " + $scope.name); $scope.$apply() }, 5000); } $scope.showText() }) </script> </body> </html>

Jak widzimy mamy tutaj prostą stronę napisaną z wykorzystaniem Bootstrap, która zawiera formularz oraz wyświetlany z inputu powyżej tekst.

Nasłuch dzięki usługi $watch powoduje wypisanie w konsoli nowej i poprzedniej wersji elementu. Pierwszy parametr name, to nazwa elementu wpisana w ng-model oraz mająca domyślną wartość Aplikacja 3, drugi to funkcja zwrotna, wykonywana podczas wykrycia zmiany w nasłuchiwanym elemencie.

Usługa $apply(), wykorzystana jest funkcji $scope.showText(), do przetworzenia danych po 5 sekundach od załadowania strony. Następuje wtedy zamiana wprowadzonego tekstu w input na Hello World oraz wyświetlenie nowego napisu w konsoli. dzięki usługi następuje również odświeżenie napisu na stronie.

Gdybyśmy nie wykorzystali tej usługi, nowy napis pojawiłby się jedynie w konsoli.

Efekt działania aplikacji

Podsumowanie

Za pomocą opisanych w tym wpisie usług możemy odświeżać dane w obiekcie $scope, tam gdzie sam AngularJS tego nie robi automatycznie. Najczęściej stosowane jest to w dużych projektach wraz z wykorzystaniem różnych frameworków. Wiedza ta na początku może wydawać się mało przydatna jednak jest to tylko złudzenia.

Pozdrawiam,
sirmarbug

Idź do oryginalnego materiału