.then w kontrolerze angular

0

Mam taki kontroler:

    angular.module('demo', [])
        .controller('Hello', function($scope, $http) {
            $http.get('http://localhost:8080/rest/cart').
            then(function(response) {
                $scope.items = response.data;
            });
            $scope.removeFromCart = function(productId) {
                $http.delete('/delete/' + productId)
                    .then(function (data) { ////////////////////////////
                        $http.get('/cart'); ///////////////////////////////
                    });
            };
        });

I o ile ze zmiennej items korzystam, żeby wyświetlić informacje o produkcie na stronie koszyka, tak z tych dwóch linijek obok których są slashe nie korzystam, bo po prostu jest button, który po naciśnięciu wywołuje funkcje removeFromCart wysyła się request DELETE, produkt jest usuwany z bazy i tyle, nic więcej mi nie trzeba. Ale usunąć tych linijek też nie mogę, bo wtedy w ogóle nic nie działa. Tak więc całokształt mi normalnie działa, ale czy mógłby się ktoś wypowiedzieć czy poz względem front-endu jest to "poprawnie" zrobione i co zrobić z tymi dwiema linijkami, skoro nie są mi potrzebne ?

1

Co znaczy, że nie działa? Musi działać, skoro z .then() działa, może po prostu nie odświeżasz widoku po usunięciu danego elementu? Masz dwie opcje:
Po wysłaniu requestu DELETE usuń dany element ze $scope.items, lub pod otrzymaniu odpowiedzi, że DELETE się wykonało prawidłowo, wyślij jeszcze raz GET i zaktualizuj $scope.items.

0

Dobra, trochę to pozmieniałem, aktualnie mam:

cartController w angularze:

angular.module('demo', [])
    .controller('Hello', function($scope, $http) {
        $scope.refreshCart = function() {
        $http.get('http://localhost:8080/rest/cart')
            .success(function(response) {
                $scope.items = response.data;
            });
    };
        $scope.removeFromCart = function(productId) {
            $http.delete('/delete/' + productId)
                .success(function (data) {
                    $scope.refreshCart();
                });
        };
        $scope.addToCart = function(productId) {
            $http.put('/add/'+ productId)
                .then(function(response) {
                    $scope.refreshCart();
            });
        };
    });

Jeden plik widoku (tutaj wszystko działa):

 <a href = "#" type="button" class="btn btn-info" th:attr="
                           ng-click='addToCart(' + ${product.id} + ')'" data-toggle="modal" data-target="#myModal">
                                Doodaj do koszyka</a>

I drugi plik widoku:

<html lang="en" xmlns:th="http://www.thymeleaf.org" ng-app="demo">
<script src="http://localhost:8080/cartController.js"></script>
<body ng-controller="Hello">

(...)
 <tbody ng-repeat="item in items.cartItemList">
            <div class="row">
                    <h4 class="nomargin">{{item.product.name}}</h4>
                    <p>{{item.product.description}}</p>
            </div>
        <td data-th="Price">{{item.price}} PLN</td>
        <td data-th="Quantity">{{item.quantity}}</td>
        </tbody>
(...)

I problem polega na tym, że funkcja addToCart w pierwszym pliku wykonuje się, request jest wysyłany, ale zmienna item w drugim pliku jest cały czas pusta. Nie wiem gdzie jest błąd ;/

0
  1. Przede wszystkim, czym są dwa pliki widoku? Jeśli masz dwa pliki HTML i w każdym z nich ng-app="demo", to masz dwie, niezależne aplikacje. Masz dwie opcje, zależy czy robisz SPA czy MPA. Przy SPA powinieneś mieć jeden główny HTML i używać routes do zmiany widoków, przy MPA dla tych różnych widoków powinieneś mieć oddzielne moduły, które w zależnościach mają jeden wspólny moduł "demo"
  2. Jakiej wersji AngularaJS używasz? Wygląda na starą, nie powinieneś używać .success() a .then().catch();
0
shagrin napisał(a):
  1. Przede wszystkim, czym są dwa pliki widoku? Jeśli masz dwa pliki HTML i w każdym z nich ng-app="demo", to masz dwie, niezależne aplikacje. Masz dwie opcje, zależy czy robisz SPA czy MPA. Przy SPA powinieneś mieć jeden główny HTML i używać routes do zmiany widoków, przy MPA dla tych różnych widoków powinieneś mieć oddzielne moduły, które w zależnościach mają jeden wspólny moduł "demo"

To są po prostu dwa pliki HTML. Tak każdy z nich ma ng-app="demo". To jak wtedy najprościej zrobić, że jeżeli w jednym pliku naciskam przycisk i wywołuję funkcję $scope.addToCart to w drugim mogę odwoływać się do zmiennej items ?

  1. Jakiej wersji AngularaJS używasz? Wygląda na starą, nie powinieneś używać .success() a .then().catch();

1.4.3, taka akurat była w oficjalnym tutorialu Springowym. Zdaję sobie sprawę, że muszę ją zaktualizować.

0

Tu masz przykład: http://blog.robertjesionek.com/angularjs-and-multi-page-applications/ W artykule jest też link do projektu na github.

Podnieś Angulara do wersji 1.6.8

0

Poczytałem trochę o co w tym chodzi i doszedłem do wniosku, że będą potrzebne 2 kontrolery i wymienię między nimi informacje za pomocą serwisu typu factory. Doszedłem do czegoś takiego:

var app = angular.module('demo', [])

app.factory("items",function(){
    return {};
});

    app.controller('Hello', function($scope, $http, items) {
        $scope.items = items;
        $scope.refreshCart = function() {
            $http.get('http://localhost:8080/rest/cart')
                .success(function(response) {
                    $scope.items = response.data;
                });
        };
        $scope.addToCart = function(productId) {
            $http.put('/add/'+ productId)
                .then(function(response) {
                    $scope.refreshCart();
                });
        };
    });

app.controller('HelloTwo', function($scope, $http, items) {
    $scope.items = items;
    $scope.refreshCart = function () {
        $http.get('http://localhost:8080/rest/cart').then(function (response) {
            $scope.items = response.data;
        });
    };
    $scope.removeFromCart = function(productId) {
        $http.delete('/delete/' + productId)
            .then(function (data) {
                $scope.refreshCart();
            });
    };
});

Ale items w drugim kontrolerze nadal jest puste ;/ Wcześniej przygotowałem w mniejszej skali i wzorowałem się na:

https://www.w3schools.com/code/tryit.asp?filename=FOWUJM7O7T4B

0

To nie jest kwestia samych kontrolerow, ale powiazan miedzy modulami. Majac jeden modul "demo" i dwa ng-app="demo" tworzysz nie jedna, ale dwie oddzielne aplikacje. Powienes miec jeden glowny modul, ktory powinien byc przekazywany jako zaleznosc do pozostalych.
Tu masz szkielet takiej aplikacji https://github.com/jesion/angularjs-mpa-skeleton

0

Przede wszystkich oba kontrolery posiadają izolowany $scope więc wymiana danych pomiędzy nimi może odbywać się poprzez eventy w angularze poczytaj o $on, $broadcast oraz $emit lub serwis/fabrykę.
$emit działa w zasięgu jednego konkretnego $scope
$broadcast wyzwala event listenery globalnie - nieznależnie od kontrolera i jego umiejscowienia. Czasem może wystąpić konieczność wyzwolenia event'u z poziomu $rootScope.

Co chodzi o funkcję then to serwis $http zwraca Ci obietnicę (promise) więc wykonanie funkcji then jest koniecznością. Jeżeli nie ma potrzeby aby robić cokolwiek w funkcji zwrotnej przekazanej do wywołania then możesz zrobić coś takiego: $http.get().then(angular.noop);

0

Widzę, że używasz bootstrap'a polecam korzystać z tej biblioteki jeżeli piszesz w angularze: https://angular-ui.github.io/bootstrap/
W oknie modalnym chcesz wylistować przedmioty dodane do koszyka oraz dać możliwość użytkownikowi na usunięcie tych przedmiotów tak?

0

Tak, dokładnie. Na stronie produktu dodaje do koszyka wysyłając request (funkcja addToCart w 3. poście). A na stronie koszyka chce je wylistować i móc usuwać (funkcja removeFromCart). To drugie udało mi się zrobić. Po prostu gdy dodaję produkt i pobieram JSONa do zmiennej items (funkcja refreshCart), to nie mogę się odwołać do tej zmiennej na stronie koszyka (jest pusta).

1 użytkowników online, w tym zalogowanych: 0, gości: 1