Reputation: 13233
I would really like to know how to set the right property for the right object.
Currently in the "change" event handler I have no knowledge of the scope I'm in. Effectively I don't know which location I should update.
Plunker: http://plnkr.co/edit/T4aBzND7VV2gCkui0I7P?p=preview
Code highlights
app.controller('MyCtrl', ['$scope', function ($scope) {
$scope.locations = ['Paris', 'London'];
}]);
app.directive('timezone', function(timezones) {
var _updateSetting = function(e) {
console.log(e.target.value);
// How do I update objects in my scope?
// (cannot access here)
};
return {
restrict: 'E',
link: function(scope, el, attrs) {
el.select2( { data: timezones.get() } ).on("change", _updateSetting);
},
template : "<input type='hidden' class='timezoneSelector' style='width: 100%;'>"
}
});
app.factory('timezones', function() {
var timezones = ["Europe/London", "Europe/Paris"];
var timezonesSelect = timezones.map(function(obj) { return {id: obj, text: obj }; } );
// preparing data so it is ready to use for select2
return {
get : function() { return timezonesSelect; }
}
});
Note: I don't want to use https://github.com/angular-ui/ui-select2 I want to stay closer to my code, be in control :)
Note: Select2 constructs some off-screen divs, and I could potentially lookup $(e.target).parent().text()
but it just look ugly to me
If you have any suggestions how to do this properly in "angular way" - let me know in the answers / comments :)
Upvotes: 1
Views: 989
Reputation: 7622
You could access the scope by passing it as parameter as in @urban_racoons' answer. However, as you are using events outside Angular, you will have to let it know you have updated scope by using $apply
.
app.directive('timezone', function(timezones) {
var _updateSetting = function(scope, e) {
console.log(e.target.value);
// now you can update scope
};
return {
restrict: 'E',
link: function(scope, el, attrs) {
el.select2( { data: timezones.get() } ).on("change", function(e) {
scope.$apply( function() {
_updateSetting(scope, e);
});
});
},
template : "<input type='hidden' class='timezoneSelector' style='width: 100%;'>"
}
});
Upvotes: 4
Reputation: 3497
I'm not sure if this is my favorite way of doing this, but it should work for what you're interested in:
app.directive('timezone', function(timezones) {
var _updateSetting = function(locations) {
console.log(locations);
};
return {
restrict: 'E',
link: function(scope, el, attrs) {
el.select2( { data: timezones.get() } ).on("change", function() {
_updateSetting(scope.locations);
});
},
template : "<input type='hidden' class='timezoneSelector' style='width: 100%;'>"
}
});
Upvotes: 1