uslugi $scope

Usługi $scope

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, że 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 class="col-xs-4 col-sm-4 col-md-4 col-lg-4 col-xs-offset-4 col-sm-offset-4 col-md-offset-4 col-lg-offset-4 panel panel-default">
        <h1 class="text-center">{{name}}</h1>

        <form class="form-inline" role="form">
            <div class="form-group">
                <input type="text" class="form-control" 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 za pomocą 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. Za pomocą 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

Podziel się ze znajomymi