Hi Mauro,
Within each iteration of the ng-repeat a *new* scope is created which inherits from its parent, in this case MainCtrl. These new scopes inherit the properties and methods of your MainCtrl which is why you can call 'addSelected' in your event handler. However, when you refer to 'selected' in your ng-model, when the value changes it is assigned to a property directly on these child scopes, not on MainCtrl. So in your plunker 'addSelected(selected)' works because the child scope knows about the method from its parent scope, and can pass in the 'selected' property directly from itself.
When you put your $watch code on MainCtrl's scope, it is looking for a 'selected' model on MainCtrl which doesn't exist, and it knows nothing about those child scopes that ng-repeat created. You need to make sure that those child scopes refer to exactly one model that you can access on MainCtrl, and you do this by referring to something inside an Object. So finally (!), here is your code modified to use $watch:
http://plnkr.co/edit/TfVU4CYjzfWN2UQZmwld
The rule of thumb to avoid this problem is 'if you use ng-model there has to be a dot somewhere'.
Hope that helps explain things.
Amir