Reputation: 19232
I am using an attribute directive to update the DOM, a variable called profileImage
. The attribute directive is called ppt-profile-icon
and works fine as long as it is not inside ng-repeat
. I have looked through a myriad of questions on Stackoverflow and have not found a solution.
Here is my HTML:
<div class="img-preview" ng-style="{'background-image': 'url(' + profileImage + ')'}"></div>
<ul class="dropdown-menu pre-defined-icons" uib-dropdown-menu role="menu" aria-labelledby="single-button">
<li ng-repeat="predefinedImage in vm.predefinedImages">
<a>
<img ppt-profile-icon src="{{predefinedImage}}" width="100%" />
</a>
</li>
<!--This, outside of the ng-repeat will work-->
<li>
<a>
<img ppt-profile-icon src="content/img/people/noProfileIcon.svg" width="100%" />
</a>
</li>
</ul>
And here is my directive:
angular
.module('app.core')
.directive('pptProfileIcon', function ($timeout) {
//link function for DOM Minipulation
function linkFunction(scope, elem, attrs) {
elem.bind('click', function () {
scope.profileImage = attrs.src;
scope.$apply();
});
}//end
//Directive Declaration
return {
restrict: "A",
controller: ['$scope', function ($scope) {
//sets enviornment
}],
link: linkFunction
}//end
});//end
In my link
function I have tried:
attrs.$observe('src', function (val) {
$timeout(function () {
scope.profileImage = val;
scope.$apply();
});
});
$timeout(function () {
scope.profileImage = attrs.src;
scope.$apply();
});
Upvotes: 1
Views: 1081
Reputation: 15472
you should always use object in your ngModels when interacting between parend - child scopes (see https://github.com/angular/angular.js/wiki/Understanding-Scopes for more details), so just adding vm.model before primitives would be sufficient:
<div class="img-preview"
ng-style="{'background-image': 'url(' + vm.model.profileImage + ')'}"></div>
and in the link function:
//link function for DOM Minipulation
function linkFunction(scope, elem, attrs) {
elem.bind('click', function () {
scope.vm.model.profileImage = attrs.src;
scope.$apply();
});
}//end
plunker: http://plnkr.co/edit/jddW7zURZoyLA8MKkm6t?p=preview
Upvotes: 1
Reputation: 165058
Problem is, scope
in your directive is the ngRepeat
directive's scope, not the parent so you're only setting profileImage
within the repeater.
I'd go with an executable binding
.directive('pptProfileIcon', function() {
return {
restrict: 'A',
scope: {
pptProfileIcon: '&'
},
link: function(scope, elem) {
elem.on('click', function() {
scope.pptProfileIcon({
profileImage: elem.prop('src')
});
scope.$apply();
});
}
}
})
Then, create a function in your controller scope to set the image
$scope.setProfileImage = function(image) {
$scope.profileImage = image;
};
and set your template like this
<img ppt-profile-icon="setProfileImage(profileImage)" ng-src="{{predefinedImage}}" />
Plunker demo ~ http://plnkr.co/edit/GqFXqZW5AmLCyWHblBDN?p=preview
Upvotes: 1