Reputation: 85
I can see no apparent reason why the ng-click
shouldn't work, however it does not fire when clicking the element it is bound to.
There are two elements that will be rendered. Each one has an icon X on on the top right of its div which should fire deletePreview
. This will lead currently to the deletion of the first item of linkPreviews
. When invoking this method by $timeout
e.g., it works as expected. Trying to click on the icon however is not working.
I'm glad for any ideas.
(function (angular) {
'use strict';
angular
.module('commons.ui')
.directive('linkPreview', linkPreview)
.controller('LinkPreviewController', LinkPreviewController);
function linkPreview() {
return {
restrict: 'E',
replace: true,
templateUrl: 'link-preview/link-preview.html',
scope: {},
require: 'ngModel',
bindToController: {
focusVar: '=?',
placement: '@'
},
controller: 'LinkPreviewController',
controllerAs: '$ctrl'
};
}
function LinkPreviewController($log, $timeout) {
var vm = this;
vm.deletePreview = deletePreview;
vm.linkPreviews = [
{
image: {
fileId: 'f616157b-223d-46ff-ba87-c16d10e83ed6',
senderId: '1ae6f889-f27e-4466-a0a9-021923704097'
},
title: 'Title',
description: 'This is an integrated platform for your official company news, social collaboration and team messaging.',
url: 'http://www.sample.com/en/tour',
tld: 'sample.com'
},
{
image: '',
title: 'Hacker News',
description: 'News for the technically interested',
url: 'https://news.ycombinator.com/',
tld: 'news.ycombinator.com'
}
];
function deletePreview() {
$log.info('should be deleted');
vm.linkPreviews.splice(0, 1);
}
}
})(angular);
<div ng-repeat="linkPreview in $ctrl.linkPreviews">
<div class="link-preview">
<div class="link-preview-delete pull-right">
<div class="link-preview-delete pull-right">
<span class="link-preview-delete-button" ng-click="$ctrl.deletePreview()">
<i class="zmdi zmdi-close img-close"></i>
</span>
</div>
</div>
..
</div>
</div>
Upvotes: 0
Views: 2270
Reputation: 3822
You need to add empty dependency
to your module, Like:
angular.module('commons.ui', [])
and, have to use controller as
syntax(if not used) in HTML, Like:
ng-controller="LinkPreviewController as $ctrl"
Working Demo :
angular
.module('commons.ui', [])
.directive('coyoLinkPreview', linkPreview)
.controller('LinkPreviewController', LinkPreviewController);
function linkPreview() {
return {
restrict: 'E',
replace: true,
templateUrl: 'app/commons/ui/components/link-preview/link-preview.html',
scope: {},
require: 'ngModel',
bindToController: {
focusVar: '=?',
placement: '@'
},
controller: 'LinkPreviewController',
controllerAs: '$ctrl'
};
}
function LinkPreviewController($log, $timeout) {
var vm = this;
vm.deletePreview = deletePreview;
vm.linkPreviews = [{
image: {
fileId: 'f616157b-223d-46ff-ba87-c16d10e83ed6',
senderId: '1ae6f889-f27e-4466-a0a9-021923704097'
},
title: 'Go COYO',
description: 'COYO is an integrated platform for your official company news, social collaboration and team messaging.',
url: 'http://www.coyoapp.com/en/tour',
tld: 'coyoapp.com'
}, {
image: '',
title: 'Hacker News',
description: 'News for the technically interested',
url: 'https://news.ycombinator.com/',
tld: 'news.ycombinator.com'
}];
function deletePreview() {
console.log('clicked');
$log.info('should be deleted');
vm.linkPreviews.splice(0, 1);
}
}
<script src="https://code.angularjs.org/1.5.2/angular.js"></script>
<div ng-app="commons.ui" ng-controller="LinkPreviewController as $ctrl">
<div ng-repeat="linkPreview in $ctrl.linkPreviews">
<div class="link-preview">
<div class="link-preview-delete pull-right">
<div class="link-preview-delete pull-right">
<span class="link-preview-delete-button" ng-click="$ctrl.deletePreview()">
<i class="zmdi zmdi-close img-close">spanToClick</i>
</span>
</div>
</div>
</div>
</div>
</div>
Update:
In your directive you are using scope:{}
, which creates isolated scope
, So your code doesn't work.
Now further ng-repeat
create new child scope
, So your div gets repeated
but internal logic of ng-repeat
like delete click is under new child scope
, So it doesn't work.
If you'll do $parent.$ctrl
then it will point to parent and will work.
See this plunker
Overall easiest fix is to remove isolated scope from directive. scope: {}
Upvotes: 1
Reputation: 85
I guess it is a bug in AngularJS? Or I indeed misused it.
In my example, the top html element of the directive is <div ng-repeat="linkPreview in $ctrl.linkPreviews">
, meaning that multiple divs will be added on the same hierarchy level.
When wrapping this in another div, as the example of @anoop showed, it'll all of a sudden work. What I don't understand yet is, why is the array of vm.linkPreviews
is always attached to the controller, however the function vm.deletePreviews
will only work when it is wrapped in one top div.
Working HTML code:
<div>
<div ng-repeat="linkPreview in $ctrl.linkPreviews">
<div class="link-preview">
<div class="link-preview-delete pull-right">
<span class="link-preview-delete-button" ng-click="$ctrl.deletePreview()">
<i class="zmdi zmdi-close img-close"></i>
</span>
</div>
<div class="link-preview-image-wrapper">
<div class="link-preview-image">
<coyo-image-reference ng-if="linkPreview.image"
file-id="::linkPreview.image.fileId"
sender-id="::linkPreview.image.senderId"
size-definitions="{'default': 'S', 'screen-lg': 'S'}"></coyo-image-reference>
<div class="link-preview-icon" ng-if="!linkPreview.image">
<i class="zmdi zmdi-globe"></i>
</div>
</div>
</div>
<div class="link-preview-text-wrapper">
<div class="link-preview-line">
<span class="link-preview-title" ng-bind="::linkPreview.title"></span>
</div>
<div class="link-preview-line">
<span class="link-preview-description" ng-bind="::linkPreview.description"></span>
</div>
<div class="link-preview-line">
<span class="link-preview-url">
<a href="{{ ::linkPreview.url }}" target="_blank">{{ ::linkPreview.tld }}</a>
</span>
</div>
</div>
</div>
</div>
</div>
Upvotes: 0
Reputation: 85
You wrong the function declaration in controller.
To use function from controller you need to set it like
this.deletePreview
or
$scope.deletePreview
(in this last case you haven't to write $ctrl
in the ng-click
view. Remember to inject $scope
!).
Upvotes: 0