Closed RogerMito closed 7 years ago
Is the context menu generated each time? If so you can just pre-load it instead of loading it when the user invokes the context menu. This way, when your context menu is invoked, it will already have the data.
Something like:
$scope.menuOptions = [];
$http.get(...).then(function(resp) {
//... extract data from resp
$scope.menuOptions = [
//...AJAX data
];
});
EDIT: as of https://github.com/Templarian/ui.bootstrap.contextMenu/commit/950a13f6733cc082deeaf211e57ff445597c7b9d you can now use a promise for the menuOptions
Hello @josetaira . I'm trying to do something similar and even implemented a promisse:
$scope.rightClick = function (text, parent, index, idPanel){
$scope.buffer = angular.copy(text);
let promisse = monitorService.getExternalLinks($scope.buffer.idVariavel).then(function (response) {
return response.data;
});
$q.when(promisse).then(function (response) {
// $scope.menuOption = response.data --> others operations for mouting context menu
}
}
rightClick send info to the selected item to obtain the new data for $scope.menuOption.
However, the context-menu directive is invoked before the data is available in $scope.menuOption.
follow my html code:
I hope you can help me thank you.
Try this:
$scope.rightClick = function (text, parent, index, idPanel){
$scope.buffer = angular.copy(text);
var deferred = $q.defer();
// This is the important part
$scope.menuOption = deferred.promise;
let promisse = monitorService.getExternalLinks($scope.buffer.idVariavel).then(function (response) {
return response.data;
});
$q.when(promisse).then(function (response) {
// Do something with response data
// After doing something with response data
deferred.resolve(<the array of objects>);
}
}
This should delay the context menu until the deferred.resolve
is executed.
Your HTML code isn't available so I'm not sure how to help you completely.
I'm sorry. I forgot to signal the passage HTML... This is my HTML (simplified):
<div ng-right-click="rightClick(x, $parent.$index, $index)" context-menu="menuOptions">
[...]
</div>
I'll try what you mentioned.
Hello @josetaira! I solve my problem! : D I did not know the $q.defer( ), only $q.all( ) and $q.when( ). Here's my code:
$scope.rightClick = function (text, parent, index, idPanel) {
var deferred = $q.defer();
$scope.menuOptions = deferred.promise;
let promisse = monitorService.getExternalLinks($scope.buffer.idVariavel).then(function (response) {
return response.data;
});
$q.when(promisse).then(function (response) {
//in this step, the object modeling is performed as expected by the context menu
deferred.resolve(buildMenuContent());
})
function buildMenuContent() {
let itemsArray = [];
for (let item of response) {
customHtml = "<a href='#' style= 'text-align: left; padding-right: 8px' id =" + item.idLink + ">" + item.nomeLink + "</a>";
itemsArray.push({
html: customHtml,
text: item.nomeLink,
click: function ($itemScope, $event, modelValue, text, $li) {
loop: {
for (let x of $scope.menuOptions.$$state.value) {
if (x.link === parseInt($li[0].firstChild.id)) {
if (item.isModal == false) {
$window.open(x.url, '_blank');
}
else {
$rootScope.$broadcast('changeUrl');
$('#openModal').modal('show');
$scope.externalUrl = $sce.trustAsResourceUrl(x.url);
}
break loop;
}
}
}
},
link: item.idLink,
url: item.caminhoLink = item.enviaIdPainel ? item.caminhoLink + panel.painelUsuario : item.caminhoLink
});
}
return itemsArray;
}
}
This may be useful for other people who need to get the menu options via ajax calls.
Thank you very much.
Hello.
Firstly, I would like to congratulate the team for their work.
I was able to solve my problem. In this case, context menu construction parameters are obtained from a database via AJAX calls. Once the information is available, I build a custom html (customHtml). After that, I make the attachment an id for each customHtml (this id is referring to some URLs that I should access after clicking on a context menu item). Through $ li access, I get the id of each element and identify the item that was selected.
I had to do something like: Loop: { For (let x of $ scope.menuOptions) { If (x.link == parseInt ($ li [0] .firstChild.id)) { $ Scope.srcPI = $ sce.trustAsResourceUrl (x.url); Break loop; } } }
However, I still have another problem that is related to context menu rendering. As my data is obtained via AJAX the context-menu policy is invoked before the information is available. Investigating the source code of the library I noticed that it returns a function. I should be able to redo the policy from the instant my data was available.
I thought about using $ rootScope, $ broadcast, and $ scope. $ On to signal the arrival of the data. However, I still have no idea how to adapt the library code to do this.
Would you have any suggestions?
Thank you very much.