Search code examples
angularjsangularjs-directiveangularjs-scope

Angularjs addmore directive and scope management


I am trying to create a directive which has addmore button.

In the controller I have a tickets obj which is empty. I am trying to add new tickets (multiple) to this obj while clicking "Add Tickets".

What I need is

  • Each ticket should increment by 1.
  • The ticket price should be updated in tickets array when a price is updated in input box (two way binding).
  • Should be able to update the quantity from controller or directive which should update in quantity input (one way binding).

I have created a plunker , any help would be appreciated, have spend lot of time in this.


Solution

  • Fancy solution with components

    I forked your plunker here with a component version.

    When you can, I recommand you the use of components over directives.

    I splitted it in two components, that's way easier to separate the functionnalities. One components for the list, and an other for one item representation.

    tickets component

    It handles the ng-repeat on components, the add button and the sum functions.

    app.component('tickets', {
      template: '<div ng-repeat="ticket in $ctrl.tickets">#{{ticket.id}}<ticket ng-change="$ctrl.recompute()" assign="$ctrl.assign" ng-model="ticket"/></div><hr><button ng-click="$ctrl.addOne()">Add One</button><br>Total price : {{$ctrl.price}}<br>Total quantity : {{$ctrl.quantities}}',
      controller: class Ctrl {
        $onInit() {
          this.tickets = [];
          this.price = 0;
          this.quantities = 0;
        }
    
        count() {
          return this.tickets.length;
        }
    
        addOne() {
          this.tickets.push({
            id: this.count(),
            price: 0,
            color: 'red',
            quantity: 1
          });
          this.recompute();
        }
    
        recompute() {
          this.price = 0;
          this.quantities = 0;
          this.tickets.forEach((ticket) => {
            this.price += ticket.price;
            this.quantities += ticket.quantity;
          });
        }
    
        assign(ticket) {
          console.log("ticket Assigned : ", ticket);
        }
      }
    });
    

    ticket component

    It handles the representation and actions for one ticket.

    app.component('ticket', {
      template: '<div><label>Quantity</label><input type="number" ng-model="$ctrl.ticket.quantity" ng-change="$ctrl.ngChange"/><br><label>Price</label><input type="number" ng-model="$ctrl.ticket.price" ng-change="$ctrl.ngChange"/><br><button ng-click="$ctrl.assignMe()">Assign</button></div>',
      bindings: {
        ngModel: '=',
        ngChange: '<',
        assign: '<'
      },
      controller: class Ctrl {
        $onInit() {
          this.ticket = this.ngModel;
        }
    
        assignMe() {
          this.assign(this.ticket);
        }
    
        addOne() {
          this.tickets.push({
            price: 0,
            color: 'red',
            quentity: 0
          });
        }
      }
    });
    

    Let me now if you want a version with directive.