web-dev-qa-db-fra.com

Passer des variables au contrôleur AngularJS, meilleure pratique?

Je suis un nouvel utilisateur de AngularJS et j'aime ce que j'ai vu jusqu'à présent, en particulier la liaison modèle/vue. J'aimerais utiliser cela pour construire une simple fonctionnalité "ajouter au panier".

Ceci est mon contrôleur jusqu'à présent:

function BasketController($scope) {
    $scope.products = [];

    $scope.AddToBasket = function (Id, name, price, image) {

        ...

    };
}

Et voici mon HTML:

<a ng-click="AddToBasket('237', 'Laptop', '499.95', '237.png')">Add to basket</a>

Cela fonctionne à présent, mais je doute fortement que ce soit la bonne façon de créer un nouvel objet produit dans mon modèle. Cependant, c’est là que mon manque total d’expérience AngularJS entre en jeu.

Si ce n’est pas la manière de le faire, quelle est la meilleure pratique?

68
Greg

Vous pouvez créer un service de panier. Et généralement, dans JS, vous utilisez des objets plutôt que de nombreux paramètres.

Voici un exemple: http://jsfiddle.net/2MbZY/

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

app.factory('basket', function() {
    var items = [];
    var myBasketService = {};

    myBasketService.addItem = function(item) {
        items.Push(item);
    };
    myBasketService.removeItem = function(item) {
        var index = items.indexOf(item);
        items.splice(index, 1);
    };
    myBasketService.items = function() {
        return items;
    };

    return myBasketService;
});

function MyCtrl($scope, basket) {
    $scope.newItem = {};
    $scope.basket = basket;    
}
65
Andrew Joslin

Vous pouvez utiliser ng-init dans une div externe:

<div ng-init="param='value';">
    <div ng-controller="BasketController" >
        <label>param: {{value}}</label>
    </div>
</div>  

Le paramètre sera alors disponible dans l'étendue de votre contrôleur:

function BasketController($scope) {
        console.log($scope.param);
}
86
Andrejs

Je ne suis pas très avancé dans AngularJS, mais ma solution serait d’utiliser une simple classe JS pour votre panier (au sens du script café) qui étend Array.

La beauté d’AngularJS est que vous pouvez passer votre objet "modèle" avec ng-click comme indiqué ci-dessous.

Je ne comprends pas l'avantage d'utiliser une fabrique, car je la trouve moins jolie qu'une classe CoffeeScript.

Ma solution pourrait être transformée en service, à des fins réutilisables. Mais sinon, je ne vois aucun avantage à utiliser des outils tels que l’usine ou le service.

class Basket extends Array
  constructor: ->

  add: (item) ->
    @Push(item)

  remove: (item) ->
    index = @indexOf(item)
    @.splice(index, 1)

  contains: (item) ->
    @indexOf(item) isnt -1

  indexOf: (item) ->
    indexOf = -1
    @.forEach (stored_item, index) ->
      if (item.id is stored_item.id)
        indexOf = index
    return indexOf

Ensuite, vous initialisez ceci dans votre contrôleur et créez une fonction pour cette action:

 $scope.basket = new Basket()
 $scope.addItemToBasket = (item) ->
   $scope.basket.add(item)

Enfin, vous configurez un clic-ng sur une ancre. Dans ce cas, vous passez votre objet (récupéré de la base de données sous forme d'objet JSON) à la fonction:

li ng-repeat="item in items"
  a href="#" ng-click="addItemToBasket(item)" 
2
Diego d'Ursel