Here is the jsfiddle exemplifying my situation.
First of all, is this the correct way to create directives with the received dimensions?
Then, each directive should be isolated from the others.. hence I am using scope: {}
.
The problem is calling functions that are in the controller.. and it seems it does not receive the broadcast either..
I am sure this is a trivial problem.. I am new to Angular :)
I have a page in which I load a number of components with ng-repeat:
<div ng-app="test">
<div ng-controller="containerCtrl">
<component ng-repeat='c in components' id="c.id" my-width="{{c.width}}" my-height="{{c.height}}">
</div>
</div>
The controller:
controller('containerCtrl', function ($scope) {
$scope.components = [{ id: "c1", width: 100, height: 100 },
{ id: "c2", width: 200, height: 100 },
{ id: "c3", width: 300, height: 100 }];
//in the actual controller I am using a socket provider and doing
//socket.forward([
// 'initPage',
// 'refreshPage'
// ], $scope);
//simulating it with a simple broadcast here..
$scope.$broadcast("onSomething", "");
$scope.doSomething = function (data) {
alert("doing something");
};
}).
and the directive:
directive('component', function () {
var linkFn = function(scope, element, attrs) {
$(element).
resizable({
stop: function( event, ui ) {
scope.emitSomething(attrs.id, ui.position);
}
});
scope.$on('onSomething', function(res) {
alert("onSomething!");
});
};
return {
restrict: 'E',
template: '<div class="ui-widget-content" style="width: {{width}}px; height: {{height}}px;"></div>',
replace: true,
scope: {
width:'@myWidth',
height:'@myHeight'
},
link : linkFn
};
});
The controller executes before the link function, so your broadcast is being sent out too soon. You can delay this using $timeout
:
$timeout(function() {
$scope.$broadcast("onSomething", "");
});
To call a controller method from a directive with an isolate scope, you need to specify the method as an argument:
<component ng-repeat='c in components' id="c.id" my-width="{{c.width}}"
my-height="{{c.height}}" callbk="doSomething(data)">
and you need to use the &
syntax in the directive:
scope: {
width: '@myWidth',
height: '@myHeight',
emitSomething: '&callbk'
},
To pass parameters to that callback/controller function, you need to use the proper syntax: scope.localDirectiveName({arg1: ..., arg2: ...})
. In the fiddle, I only used one argument, and passed the two parameters in an array instead:
$(element).resizable({
stop: function (event, ui) {
scope.emitSomething({data: ["id", "position"]});
}
});
fiddle
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With