Reputation: 2996
I'm relatively new to Angularjs and I'm writing an app. The app has an array of objects, each of the objects has a private variable called status. I have two filters, which return a subset of these objects based on their status. As an example, the statuses corresponding to these two filters are 'NEW' and 'OLD' respectively.
Next, I've written a directive that makes the divs formed by these objects, draggable. Basically, what the directive does is receive the object through a two way data binding, and then changes the status of the object by calling the corresponding method.
The problem is, the changes in the status of the object doesn't update the filter instantly. For example, when I drag three of the divs to the other half, their status gets updated, but the filter doesn't.
Here's the directive:
.directive('draggable', function ($document) {
return {
scope: {
bill: '=' // the bill object
},
restrict: 'A',
link: function (scope, element, attr) {
// do something here
console.log('bill', scope.bill);
var startX = 0,
startY = 0,
x = 0,
y = 0,
sourceX = 0,
sourceY = 0,
windowWidth = 0;
element.on('mousedown', function (event) {
event.preventDefault();
startX = event.pageX - x;
startY = event.pageY - y;
$document.on('mousemove', mousemove);
$document.on('mouseup', mouseup);
windowWidth = $(window).width();
sourceY = event.pageY;
sourceX = event.pageX;
});
function mousemove(event) {
y = event.pageY;
x = event.pageX;
element.css({
top: y + 'px',
left: x + 'px'
});
}
function mouseup(event) {
$document.unbind('mousemove', mousemove);
$document.unbind('mouseup', mouseup);
console.log('mouseup', startX, startY, event.screenX, event.screenY);
var mid = windowWidth / 2;
if (sourceX < mid && event.pageX >= mid) {
// yes there was a change of sides
scope.bill.markCooking(); // change the status to COOKING
console.log('moved to COOKING', scope.bill.getStatus());
} else if (sourceX >= mid && event.pageX < mid) {
scope.bill.enq(); // change the status to NEW
console.log('moved to ENQ', scope.bill.getStatus());
}
}
}
}})
What am I doing wrong here?
Upvotes: 0
Views: 250
Reputation: 3012
Any time that you're in a browser event handler you are effectively outside of Angular's lifecycle. The user's actions have triggered the event, but Angular doesn't know that it needs to check and update its bindings (in this case, the bill status).
Calling scope.$apply()
manually triggers Angular's change detection, and will update your bindings:
scope.$apply(function() {
if (sourceX < mid && event.pageX >= mid) {
// yes there was a change of sides
scope.bill.markCooking(); // change the status to COOKING
console.log('moved to COOKING', scope.bill.getStatus());
} else if (sourceX >= mid && event.pageX < mid) {
scope.bill.enq(); // change the status to NEW
console.log('moved to ENQ', scope.bill.getStatus());
}
});
You can read more about scopes and their lifecycle here: http://docs.angularjs.org/guide/scope
Upvotes: 3