AngularJs toggle template with directive to create notification like stackoverflow - angularjs

I'm trying to create a notification system in AngularJs just like the notification used here. When there is a new comment, answer, etc.. The archive icon shows a red sign with the number of activities, and when I click on it, it opens up a box with the last notifications.
To do this, I built this simple directive to dynamic loads a templateUrl:
html:
<li test-alert ref="msg">
<i class="fa fa-envelope-o"></i>
</li>
<li test-alert ref="bell">
<i class="fa fa-bell-o"></i>
</li>
directive:
angular
.module('agApp')
.directive('testAlert', testAlert)
;
/* #ngInject */
function testAlert() {
var templateA = '<div>Test template A</div>';
var templateB = '<div>Test template B</div>';
return{
restrict: 'A',
scope: {
ref: '#'
},
link: function(scope,element,attrs,controller){
scope.showAlert = false;
element.on("click", function() {
if (scope.ref == 'bell') {
scope.showAlert = true;
element.append(templateA);
scope.$apply();
} else {
scope.showAlert = true;
element.append(templateB);
scope.$apply();
};
console.log(scope.ref);
});
element.addEventListener("keyup", function(e) {
if (e.keyCode === 27) {
scope.showAlert = false;
}
});
}
};
}; //end test alert
But I'm with some problems..
If i click on the icon to open the template it will open, but every time i click on it, it will append another template. Id' like it to change (if it's the other template) or do nothing.
When it is opened, I can't make it close. I can use a 'close' button, but I'd like to close/remove the template when the user click on the document or press esc;
The code I tried to use to close on 'Esc' key, doesn't work.
My main objective is to create a notification system just like the one in stackOverflow, so is this the best way to do it? Should I use a controller instead?
Edit:
Close mechanism I'm using at the momment. It's working, but maybe it can be improved.
run.js
angular
.module('agApp')
.run(runApp);
/* #ngInject */
function runApp($rootScope) {
document.addEventListener("keyup", function(e) {
if (e.keyCode === 27) {
$rootScope.$broadcast("escapePressed", e.target);
};
});
document.addEventListener("click", function(e) {
$rootScope.$broadcast("documentClicked", e.target);
});
}; //end run
controller.js
$rootScope.$on("documentClicked", _close);
$rootScope.$on("escapePressed", _close);
function _close() {
$scope.$apply(function() {
vm.closeAlert();
});
};
Since I wasn't able to use it as a directive, I moved the open/close function inside a controller. But it can be used in any other way, as long as it works, there is no problem.

First off, key events only fire on the document and elements that may receive focus.
Directives are really nice for things you need to use multiple times. But even if you implement your notification system as a directive and only use it once - you will have it isolated, which is often good.
Hard to give the best solution without knowing more but here is one example that implements the messages and the notifications as one directive:
app.directive('notifications',
function() {
return {
restrict: 'E',
templateUrl: 'template.html',
scope: {},
link: function(scope, element, attrs, controller) {
scope.viewModel = {
showTemplateA: false,
showTemplateB: false
};
scope.toggleTemplateA = function() {
scope.viewModel.showTemplateA = !scope.viewModel.showTemplateA;
scope.viewModel.showTemplateB = false;
};
scope.toggleTemplateB = function() {
scope.viewModel.showTemplateB = !scope.viewModel.showTemplateB;
scope.viewModel.showTemplateA = false;
};
}
};
});
It simply contains logic for showing and hiding the templates. The directive uses a template that looks like this:
<div>
<i class="fa fa-envelope-o" ng-click="toggleTemplateA()"></i>
<div ng-show="viewModel.showTemplateA">
Template A
</div>
<br>
<i class="fa fa-bell-o" ng-click="toggleTemplateB()"></i>
<div ng-show="viewModel.showTemplateB">
Template B</div>
</div>
The template uses ng-show and ng-click to bind to our scope functions. This way we let Angular do the job and don't have to mess around with element.append etc.
Usage:
<notifications></notifications>
Demo: http://plnkr.co/edit/8M1D5uENjpDoIbb1ZuMR?p=preview
To implement your closing mechanism you can add the following to the directive:
var close = function () {
scope.$apply(function () {
scope.viewModel.showTemplateA = false;
scope.viewModel.showTemplateB = false;
});
};
$document.on('click', close);
$document.on('keyup', function (e) {
if (e.keyCode === 27) {
close();
}
});
scope.$on('$destroy', function () {
$document.off('click', close);
$document.off('keyup', close);
});
Note that you now have to inject $document into the directive:
app.directive('notifications', ['$document',
function($document) {
In the toggle functions you can call stopPropagation() to prevent the global closing handler to execute when you click the icons (might not be needed in this example, but good to know. Might want it on the actual templates in the future?):
scope.toggleTemplateA = function($event) {
$event.stopPropagation();
And:
ng-click="toggleTemplateA($event)"
Demo: http://plnkr.co/edit/LHS4RBE7qtY4yNyEdR16?p=preview

Related

AngularJS directive with ng-show not toggling with change in variable

I'm trying to create a simple html5 video playlist app. I've got an overlay div on top of the html5 video that should appear/disappear when stopping and starting the video.
I've got ng-show and a variable to trigger it, but it's not changing when I look using ng-inspector.
My events might not be quite correct, either - but I can't seem to find much information on putting events on different elements within the same directive. Is this a clue that I should break this up into multiple directives?
(function() {
'use strict';
angular
.module('app')
.controller('campaignController', campaignController)
.directive('myVideo', myvideo);
function campaignController($log,Campaign) {
var vm = this;
vm.overlay = true;
Campaign.getCampaign().success(function(data) {
vm.campaign = data[0];
vm.item = vm.campaign.videos[0];
});
vm.select = function(item) {
vm.item = item;
};
vm.isActive = function(item) {
return vm.item === item;
};
};
function myvideo() {
return {
restrict: 'E',
template: ['<div class="video-overlay" ng-show="vm.overlay">',
'<p>{{ vm.campaign.name}}</p>',
'<img class="start" src="play.png">',
'</div>',
'<video class="video1" controls ng-src="{{ vm.item.video_mp4_url | trusted }}" type="video/mp4"></source>',
'</video>' ].join(''),
link: function(scope, element, attrs) {
scope.video = angular.element(document.getElementsByClassName("video1")[0]);
scope.startbutton = angular.element(document.getElementsByClassName("start")[0]);
scope.startbutton.on('click', function() {
scope.vm.overlay = false;
scope.video[0].play();
});
scope.video.on('click', function() {
scope.video[0].pause();
scope.vm.overlay = true;
});
}
};
}
})();
From my personal experience angular expression evaluation does not work as javascript. so try ng-show="vm.overlay==true".
Furthermore you bind click using native javascript.
Either don't do that and use ng-click or call scope.$apply() in the click event t callbackas last intruction (even though i'm not sure if it's really important).

Angular JS conditional logic to check "class name" exists

Below Angular JS code works fine on Mouseover & Mouseout. Need help regard adding conditional logic on JS code.
If class name "active" exists, img src path have to be in "overImg" even if user mouseover & mouseout. But, present behaviour removes overImg once user mouseout from element. Active state have to be different from the rest of navigation element.
AngularJS:
.directive('eleHoverAction', function() {
return {
link: function (scope, elem, attrs) {
var imgObj = $(elem).find('img');
var upImg = attrs.eleUpImgSrc;
var overImg = attrs.eleOverImgSrc;
elem.bind('mouseover', function () {
$(imgObj).attr("src", overImg);
scope.$apply();
});
elem.bind('mouseout', function() {
$(imgObj).attr("src", upImg);
scope.$apply();
});
}
};
});
HTML:
<li class="menu-item menu-item--category active" ele-hover-action ele-up-img-src="images/test1.png" ele-over-img-src="images/test1-over.png">
<img src="images/test1.png" oversrc="images/test1-over.png" alt=""/><span>Test1</span>
</li>
<li class="menu-item menu-item--category" ele-hover-action ele-up-img-src="images/test2.png" ele-over-img-src="images/test2-over.png">
<img src="images/test2.png" oversrc="images/test2-over.png" alt=""/><span>Test2</span>
</li>
The most obvious method is to add an if statement to your "mouseout" handler that checks if the element hasClass active:
.directive('eleHoverAction', function() {
return {
link: function (scope, elem, attrs) {
var imgObj = elem.find('img');
var upImg = attrs.eleUpImgSrc;
var overImg = attrs.eleOverImgSrc;
elem.bind('mouseover', function () {
imgObj.attr("src", overImg);
scope.$apply();
});
elem.bind('mouseout', function() {
if (!elem.hasClass("active")) {
imgObj.attr("src", upImg);
}
scope.$apply();
});
if (elem.hasClass("active")) {
imgObj.attr("src", overImg);
} else {
imgObj.attr("src", upImg);
}
}
};
});
I went ahead and set the src attribute of the image based on the directive attributes. You could just take that part out if you don't want it. Also, wrapping elem in a jQuery call is redundant because Angular elements are already wrapped in either jQuery (if available when Angular loads) or its own jQLite. Otherwise, you wouldn't be able to call elem.bind.
Try it in a fiddle.

Good way to dynamically open / close a popover (or tooltip) using angular, based on expression?

I have a form that is wired into angular, using it for validation. I am able to display error messages using ng-show directives like so:
<span ng-show="t3.f.needsAttention(f.fieldName)" ng-cloak>
<span ng-show="f.fieldName.$error.required && !f.fieldName.$viewValue">
This field is required.
</span>
</span>
.. where f is the form, and t3 comes from a custom directive on the form which detects whether a submission was attempted, and contains functions for checking the validity of fields.
What I am trying to accomplish is to display validation message(s) inside a popover instead. Either bootstrap's native popover, or the popover from UI Bootstrap, I have both loaded. I may also consider AngularStrap if it is easier to do it using that lib.
What I'm struggling with right now is the nature of popovers in general -- they autodisplay based on user events like click, mouseenter, blur, etc. What I want to do is show & hide the popover(s) based on the same functions in the ng-show attributes above. So that when the expression returns false hide it, and when it returns true, show it.
I know bootstrap has the .popover('show') for this, but I'm not supposed to tell angular anything about the dom, so I'm not sure how I would get access to $(element).popover() if doing this in a custom form controller function. Am I missing something?
Update
The solution mentioned in the duplicate vote still only shows the popover on mouseenter. I want to force it to display, as if doing $('#popover_id').popover('show').
You can also build your own extended triggers. This will apply to both Tooltip and Popover.
First extend the Tooltip triggers as follows:
// define additional triggers on Tooltip and Popover
app.config(['$tooltipProvider', function($tooltipProvider){
$tooltipProvider.setTriggers({
'show': 'hide'
});
}]);
Then define the trigger on the HTML tag like this:
<div id="RegisterHelp" popover-trigger="show" popover-placement="left" popover="{{ 'Login or register here'}}">
And now you can call hide and show from JavaScript, this is a show in 3 seconds.
$("#RegisterHelp").trigger('show');
//Close the info again
$timeout(function () {
$("#RegisterHelp").trigger('hide');
}, 3000);
As it turns out, it's not very difficult to decorate either the ui-bootstrap tooltip or the popover with a custom directive. This is written in typescript, but the javascript parts of it should be obvious. This single piece of code works to decorate either a tooltip or a popover:
'use strict';
module App.Directives.TooltipToggle {
export interface DirectiveSettings {
directiveName: string;
directive: any[];
directiveConfig?: any[];
}
export function directiveSettings(tooltipOrPopover = 'tooltip'): DirectiveSettings {
var directiveName = tooltipOrPopover;
// events to handle show & hide of the tooltip or popover
var showEvent = 'show-' + directiveName;
var hideEvent = 'hide-' + directiveName;
// set up custom triggers
var directiveConfig = ['$tooltipProvider', ($tooltipProvider: ng.ui.bootstrap.ITooltipProvider): void => {
var trigger = {};
trigger[showEvent] = hideEvent;
$tooltipProvider.setTriggers(trigger);
}];
var directiveFactory = (): any[] => {
return ['$timeout', ($timeout: ng.ITimeoutService): ng.IDirective => {
var d: ng.IDirective = {
name: directiveName,
restrict: 'A',
link: (scope: ng.IScope, element: JQuery, attr: ng.IAttributes) => {
if (angular.isUndefined(attr[directiveName + 'Toggle'])) return;
// set the trigger to the custom show trigger
attr[directiveName + 'Trigger'] = showEvent;
// redraw the popover when responsive UI moves its source
var redrawPromise: ng.IPromise<void>;
$(window).on('resize', (): void => {
if (redrawPromise) $timeout.cancel(redrawPromise);
redrawPromise = $timeout((): void => {
if (!scope['tt_isOpen']) return;
element.triggerHandler(hideEvent);
element.triggerHandler(showEvent);
}, 100);
});
scope.$watch(attr[directiveName + 'Toggle'], (value: boolean): void => {
if (value && !scope['tt_isOpen']) {
// tooltip provider will call scope.$apply, so need to get out of this digest cycle first
$timeout((): void => {
element.triggerHandler(showEvent);
});
}
else if (!value && scope['tt_isOpen']) {
$timeout((): void => {
element.triggerHandler(hideEvent);
});
}
});
}
};
return d;
}];
};
var directive = directiveFactory();
var directiveSettings: DirectiveSettings = {
directiveName: directiveName,
directive: directive,
directiveConfig: directiveConfig,
};
return directiveSettings;
}
}
With this single piece of code, you can set up programmatic hide and show of either a tooltip or popover like so:
var tooltipToggle = App.Directives.TooltipToggle.directiveSettings();
var popoverToggle = App.Directives.TooltipToggle.directiveSettings('popover');
var myModule = angular.module('my-mod', ['ui.bootstrap.popover', 'ui.bootstrap.tpls'])
.directive(tooltipToggle.directiveName, tooltipToggle.directive)
.config(tooltipToggle.directiveConfig)
.directive(popoverToggle.directiveName, popoverToggle.directive)
.config(popoverToggle.directiveConfig);
Usage:
<span tooltip="This field is required."
tooltip-toggle="formName.fieldName.$error.required"
tooltip-animation="false" tooltip-placement="right"></span>
or
<span popover="This field is required."
popover-toggle="formName.fieldName.$error.required"
popover-animation="false" popover-placement="right"></span>
So we are reusing everything else that comes with the ui-bootstrap tooltip or popover, and only implementing the -toggle attribute. The decorative directive watches that attribute, and fires custom events to show or hide, which are then handled by the ui-bootstrap tooltip provider.
Update:
Since this answer seems to be helping others, here is the code written as javascript (the above typescript more or less compiles to this javascript):
'use strict';
function directiveSettings(tooltipOrPopover) {
if (typeof tooltipOrPopover === "undefined") {
tooltipOrPopover = 'tooltip';
}
var directiveName = tooltipOrPopover;
// events to handle show & hide of the tooltip or popover
var showEvent = 'show-' + directiveName;
var hideEvent = 'hide-' + directiveName;
// set up custom triggers
var directiveConfig = ['$tooltipProvider', function ($tooltipProvider) {
var trigger = {};
trigger[showEvent] = hideEvent;
$tooltipProvider.setTriggers(trigger);
}];
var directiveFactory = function() {
return ['$timeout', function($timeout) {
var d = {
name: directiveName,
restrict: 'A',
link: function(scope, element, attr) {
if (angular.isUndefined(attr[directiveName + 'Toggle']))
return;
// set the trigger to the custom show trigger
attr[directiveName + 'Trigger'] = showEvent;
// redraw the popover when responsive UI moves its source
var redrawPromise;
$(window).on('resize', function() {
if (redrawPromise) $timeout.cancel(redrawPromise);
redrawPromise = $timeout(function() {
if (!scope['tt_isOpen']) return;
element.triggerHandler(hideEvent);
element.triggerHandler(showEvent);
}, 100);
});
scope.$watch(attr[directiveName + 'Toggle'], function(value) {
if (value && !scope['tt_isOpen']) {
// tooltip provider will call scope.$apply, so need to get out of this digest cycle first
$timeout(function() {
element.triggerHandler(showEvent);
});
}
else if (!value && scope['tt_isOpen']) {
$timeout(function() {
element.triggerHandler(hideEvent);
});
}
});
}
};
return d;
}];
};
var directive = directiveFactory();
var directiveSettings = {
directiveName: directiveName,
directive: directive,
directiveConfig: directiveConfig,
};
return directiveSettings;
}
For ui.bootstrap 0.13.4 and newer:
A new parameter (popover-is-open) was introduced to control popovers in the official ui.bootstrap repo. This is how you use it in the latest version:
<a uib-popover="Hello world!" popover-is-open="isOpen" ng-click="isOpen = !isOpen">
Click me to show the popover!
</a>
For ui.bootstrap 0.13.3 and older:
I just published a small directive that adds more control over popovers on GitHub: https://github.com/Elijen/angular-popover-toggle
You can use a scope variable to show/hide the popover using popover-toggle="variable" directive like this:
<span popover="Hello world!" popover-toggle="isOpen">
Popover here
</span>
Here is a demo Plunkr: http://plnkr.co/edit/QeQqqEJAu1dCuDtSvomD?p=preview
My approach:
Track the state of the popover in the model
Change this state per element using the appropriate directives.
The idea being to leave the DOM manipulation to the directives.
I have put together a fiddle that I hope gives a better explain, but you'll find much more sophisticated solutions in UI Bootstrap which you mentioned.
jsfiddle
Markup:
<div ng-repeat="element in elements" class="element">
<!-- Only want to show a popup if the element has an error and is being hovered -->
<div class="popover" ng-show="element.hovered && element.error" ng-style>Popover</div>
<div class="popoverable" ng-mouseEnter="popoverShow(element)" ng-mouseLeave="popoverHide(element)">
{{ element.name }}
</div>
</div>
JS:
function DemoCtrl($scope)
{
$scope.elements = [
{name: 'Element1 (Error)', error: true, hovered: false},
{name: 'Element2 (no error)', error: false, hovered: false},
{name: 'Element3 (Error)', error: true, hovered: false},
{name: 'Element4 (no error)', error: false, hovered: false},
{name: 'Element5 (Error)', error: true, hovered: false},
];
$scope.popoverShow = function(element)
{
element.hovered = true;
}
$scope.popoverHide = function(element)
{
element.hovered = false
}
}
For others coming here, as of the 0.13.4 release, we have added the ability to programmatically open and close popovers via the *-is-open attribute on both tooltips and popovers in the Angular UI Bootstrap library. Thus, there is no longer any reason to have to roll your own code/solution.
From Michael Stramel's answer, but with a full angularJS solution:
// define additional triggers on Tooltip and Popover
app.config(['$tooltipProvider', function($tooltipProvider){
$tooltipProvider.setTriggers({
'show': 'hide'
});
}])
Now add this directive:
app.directive('ntTriggerIf', ['$timeout',
function ($timeout) {
/*
Intended use:
<div nt-trigger-if={ 'triggerName':{{someCodition === SomeValue}},'anotherTriggerName':{{someOtherCodition === someOtherValue}} } ></div>
*/
return {
restrict: 'A',
link: function (scope, element, attrs) {
attrs.$observe('ntTriggerIf', function (val) {
try {
var ob_options = JSON.parse(attrs.ntTriggerIf.split("'").join('"') || "");
}
catch (e) {
return
}
$timeout(function () {
for (var st_name in ob_options) {
var condition = ob_options[st_name];
if (condition) {
element.trigger(st_name);
}
}
})
})
}
}
}])
Then in your markup:
<span tooltip-trigger="show" tooltip="Login or register here" nt-trigger-if="{'show':{{ (errorConidtion) }}, 'hide':{{ !(errorConidtion) }} }"></span>

How do I use an Angular directive to show a dialog?

Using Angular, I'm trying to create a directive that will be placed on a button that will launch a search dialog. There are multiple instances of the search button, but obviously I only want a single instance of the dialog. The dialog should be built from a template URL and have it's own controller, but when the user selects an item, the directive will be used to set the value.
Any ideas on how to create the dialog with it's own controller from the directive?
Here's what I've go so far (basically just the directive)...
http://plnkr.co/edit/W9CHO7pfIo9d7KDe3wH6?p=preview
Here is the html from the above plkr...
Find
Here is the code from the above plkr...
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
var person = {};
person.name = 'World';
$scope.person = person;
$scope.setPerson = function(newPerson) {
person = newPerson;
$scope.person = person;
}
});
app.directive('myFind', function () {
var $dlg; // holds the reference to the dialog. Only 1 per app.
return {
restrict: 'A',
link: function (scope, el, attrs) {
if (!$dlg) {
//todo: create the dialog from a template.
$dlg = true;
}
el.bind('click', function () {
//todo: use the dialog box to search.
// This is just test data to show what I'm trying to accomplish.
alert('Find Person');
var foundPerson = {};
foundPerson.name = 'Brian';
scope.$apply(function () {
scope[attrs.myFind](foundPerson);
});
});
}
}
})
This is as far as I've gotten. I can't quite figure out how to create the dialog using a template inside the directive so it only occurs once and then assign it a controller. I think I can assign the controller inside the template, but first I need to figure out how to load the template and call our custom jQuery plugin to generate the dialog (we have our own look & feel for dialogs).
So I believe the question is, how do I load a template inside of a directive? However, if there is a different way of thinking about this problem, I would be interested in that as well.
I will show you how to do it using bootstrap-ui. (you can modify it easily, if it does not suit your needs).
Here is a skeleton of the template. You can normally bound to any properties and functions that are on directive's scope:
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
... // e.g. <div class="button" ng-click=cancel()></div>
</div>
<div class="modal-body">
...
</div>
<div class="modal-footer">
...
</div>
</div>
</div>
Here is how to create/declare directive in your module:
.directive("searchDialog", function ($modal) {
return {
controller: SearchDialogCtrl,
scope : {
searchDialog: '=' // here you will set two-way data bind with a property from the parent scope
},
link: function (scope, element, attrs) {
element.on("click", function (event) { // when button is clicked we show the dialog
scope.modalInstance = $modal.open({
templateUrl: 'views/search.dialog.tpl.html',
scope: scope // this will pass the isoleted scope of search-dialog to the angular-ui modal
});
scope.$apply();
});
}
}
});
Then controller may look something like that:
function SearchDialogCtrl(dep1, dep2) {
$scope.cancel = function() {
$scope.modalInstance.close(); // the same instance that was created in element.on('click',...)
}
// you can call it from the template: search.dialog.tpl.html
$scope.someFunction = function () { ... }
// it can bind to it in the search.dialog.tpl.html
$scope.someProperty;
...
// this will be two-way bound with some property from the parent field (look below)
// if you want to perform some action on it just use $scope.$watch
$scope.searchDialog;
}
Then it your mark-up you can just use it like that:
<div class="buttonClass" search-dialog="myFieldFromScope">search</div>
I recommend this plugin:
https://github.com/trees4/ng-modal
Demo here:
https://trees4.github.io/ngModal/demo.html
Create a dialog declaratively; and it works with existing controllers. The content of the dialog can be styled however you like.

AngularJS (1.1.5): Can you cancel Directives with priority cancel

Is it possible to keep the built-in ng-click handler from firing when you have a custom ng-click directive with a priority > 0 that fires first? Or to delay the built-in one in some way?
In my case I have a custom ngClick directive that applies an animation to an element then waits for the animation to complete. Once it is complete, and only then, should the built-in ngClick fire. Reasoning is that the clicked element is on a slide-out drawer that is automatically hidden from within the ngClick handler. If the directive can't keep it from firing, then the drawer is closed before the animation even starts.
From the custom directive, I can use this to invoke the default ngClick, but the original needs to be cancelled in this case...
Requirement: The solution should not require the developer write any code within their ngClick handler. I am definitely able to code this in the controller, but want to avoid having the controller having to know that it is supposed to wait. (i.e. in case I change how the directive implements the indicator and it takes a different amount of time)
$timeout(function() {service.close();}, 400);
Here is an example of what I want to accomplish.
Markup
<li ng-repeat="product in service.products"
ng-click="onClick('{{product}}')"
pre-click="onClicking('{{product}}')"
animate="wasClicked(product)">
{{product}}
</li>
Directive
angular.module('sales.directives')
.directive('ngClick', [
'$timeout',
function ($timeout) {
return {
priority: 50, // higher priority
restrict: 'A',
scope: false,
link: function (scope, element, attributes) {
element.bind('click', function () {
if (attributes.preClick) {
eval('scope.' + attributes.preClick);
}
});
if (attributes.animate !== undefined) {
scope.$watch(attributes.animate, function (newValue) {
if (newValue == true) {
element.addClass('animated');
// pause 400ms so animation can complete
$timeout(angular.noop, 400)
.then(function () {
element.removeClass('animated');
// I would like to invoke the original
// ngClick here, and then remove it from the
// queue so that it doesn't fire it again.
// Reason for invoking it here is that if I
// don't, then the base ngClick event will
// fire before this promise is resolved.
eval('scope.' + element.ngClick);
// ??
});
}
});
}
}
};
}]);
Controller
angular.module('sales')
.controller(
'ProductController',
[
'$scope', 'ProductService',
function ($scope, $timeout, service) {
$scope.clickedProduct = null;
$scope.onClicking = function (product) {
$scope.clickedProduct = product;
};
$scope.wasClicked = function (product) {
return $scope.clickedProduct === product;
};
$scope.onClick = function (product) {
service.selected = product;
};
}
]);
Any thoughts? Is there a better way to do this?

Resources