Stif
Stif

Reputation: 935

angular 1.5 component binding not updated from certain events

I have an angular 1.5 component (i.e. myCarousel: it wraps a bootstrap carousel) that triggers an event and exposes it with a function binding. A parent container (i.e. myContainer) component binds a function to that event and modifies some inner state when triggered. Another child-component of the parent container is bound to the container's inner state.

The problem:

When I trigger the event on myCarousel from a button click event, everything works fine and I can see the child-component's binding being updated.

However, when I trigger the event from a carousel slide event (slide.bs.carousel), the binding does not get updated.

Here's a plunker to demonstrate: https://plnkr.co/edit/AHxaX8o0sE94Nfir7DVB

Can anyone explain why this is happening and how to solve this?

Some relevant code:

mainApp.component("myCarousel", {
  templateUrl: "myCarousel.html",
  bindings: {
    onEventTriggered: "&"
  },
  controllerAs: "vm",
  controller: function() {
    let vm = this;
    vm.$onInit = function() {
      console.log("init!");
      $("#theCarousel").carousel();
      $("#theCarousel").on("slide.bs.carousel", (event) => {
        console.log("sliding " + event.direction);
        vm.onEventTriggered();
      });
    };
  }
});

mainApp.component("myContainer", {
  templateUrl: "myContainer.html",
  controllerAs: "vm",
  controller: function() {
    let vm = this;
    vm.counter = 0;
    vm.triggerEvent = function() {
      console.log("event!");
      vm.counter++;

    }
  }
});

mainApp.component("childComponent", {
  template: "<div>Event {{vm.attribute}}</div>",
  controllerAs: "vm",
  bindings: {
    attribute: "<"
  }
});

Upvotes: 2

Views: 2254

Answers (1)

gaurav5430
gaurav5430

Reputation: 13892

One way to do this is :

controller: function($scope) {
    let vm = this;
    vm.$onInit = function() {
      console.log("init!");
      $("#theCarousel").carousel();
      $("#theCarousel").on("slide.bs.carousel", (event) => {
        vm.onEventTriggered();
        console.log("sliding " + event.direction);
        $scope.$apply();
      });
    };
  }

using $scope.$apply()

updated plunkr : https://plnkr.co/edit/8yZOyuQfofdoYz00tFBk?p=preview

You need to use $scope.$apply(), because $("#theCarousel").on("slide.bs.carousel", ... is jquery code, and you need to notify angular about it using $scope.$apply()

Upvotes: 3

Related Questions