You need to make a context menu in the form of the directive AngularJS. So far I have done this:

<span class="myelem" dd-ctx-menu="menuobj">ВСстовый элСмСнт</span> 

Where menuobj is an object with a list of required fields in the context menu, well, ddCtxMenu is a directive. In the directive itself, for the time being, I do everything "manually", that is, I create the element var menu = angular.element('<div class="ctxmenu"></div>'); , then in the cycle I fill it, put the handlers and display it on the screen. Everything works, but I was told there is a more correct way.

Interested in how to use the directive template to do so in advance to write the context menu construction and the framework would do the work for me to fill it.

For example, a template for a start:

 <div class="ctxmenu"> <span ng-repeat="elem in menulist">{{elem}}</span> </div> 

As I read in the documentation and made sure in practice, if you specify a template directive through templateUrl: 'template.html' , then it will overwrite the element in accordance with the template, and I need this template to be activated by click to create the menu. I still don’t know the framework and I don’t express my thoughts clearly, but I hope you understand me.

Directive code:

 (function(angular) { 'use strict'; angular.module('ctxMenuModule', []) .directive('ddCtxMenu', ['$document', function($document) { return { // ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ с настройками мСню scope: { menuobj: '=ddCtxMenu' }, link: function(scope, element, attr) { // ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ состояния элСмСнта, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‡ΠΈΠΊΠ°ΠΌΠΈ ΠΈ для isEnabled() var state = {}; //создаСм мСню ΠΈ навСшиваСм Π²Π½ΡƒΡ‚Ρ€ΡŒ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ function createCtxMenu(menuobj) { var menu = angular.element('<div class="ctxmenu"></div>'); for (let prop in menuobj) { let itemobj = menuobj[prop]; let item = angular.element('<div>' + itemobj.name + '</div>'); if (itemobj.isEnabled(state)) { item.addClass('ctxmenuitem'); item.on('click', function() { console.log('44'); itemobj.handler(element, state); }) //Ссли Π΅ΡΡ‚ΡŒ подмСню if (itemobj.submenu) { var submenu = createCtxMenu(itemobj.submenu); menu.submenu = submenu; item.on('mouseover', function(e) { e.stopPropagation(); var rect = item[0].getBoundingClientRect(); $document.find('body').append(submenu); //смСщаСм мСню. submenu.css({ top: rect.top + 'px', left: rect.right + 'px' }); }); item.on('mouseout', function(e) { var rt = e.relatedTarget ? e.relatedTarget : e.toElement; if (submenu[0] != rt && submenu[0] != rt.parentNode) { submenu.removeAll(); } }); } } else { item.addClass('ctxmenudisabled'); } menu.append(item); } //удаляСм мСню ΠΈ всС подмСню рСкурсивно menu.removeAll = function() { menu.submenu ? menu.submenu.removeAll() : 0; menu.remove(); } menu.on('mouseover', function() { menu.submenu ? menu.submenu.removeAll() : 0; }); return menu; } //отслСТиваСм ΠΏΡ€Π°Π²Ρ‹ΠΉ ΠΊΠ»ΠΈΠΊ Π½Π° элСмСнтС element.on('contextmenu', function(event) { event.preventDefault(); event.stopPropagation(); // удаляСм Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π΅ мСню var tmp = angular.element(document.querySelectorAll('.ctxmenu')); tmp.length ? tmp.remove() : 0; //создаСм Π½ΠΎΠ²ΠΎΠ΅ var ctxMenu = createCtxMenu(scope.menuobj); $document.find('body').append(ctxMenu); //ставим ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ ΠΊΠ»ΠΈΠΊΠΎΠ² var removeMenu = function() { ctxMenu.removeAll(); $document.off('click', removeMenu); $document.off('contextmenu', removeMenu); } $document.on('click', removeMenu); $document.on('contextmenu', removeMenu); //смСщаСм мСню. ctxMenu.css({ top: event.pageY + 'px', left: event.pageX + 'px' }); }); } }; } ]); })(window.angular); 

The menuobj itself is an array of objects of the form:

 $scope.menuobj = [ { name: 'Π£Π΄Π°Π»ΠΈΡ‚ΡŒ', handler: function(element, state) { element.remove(); }, isEnabled: function(state) { return true; } }, ...]; 
  • Add an example of your directive so that you can see what it does - Grundy
  • @Grundy did. - RussCoder
  • There are at least two options: try using transclude, or using the $ compile service - Grundy

0