Как дождаться загрузки изображения перед настройкой области видимости в AngularJS? - PullRequest
0 голосов
/ 07 ноября 2019

Я использую AngularJS и TypeScript. Я использую библиотеку cytoscape с расширением cytoscape-edgehandles и оболочкой ngCytoscape для AngularJS. Я пытаюсь добавить изображение в дескриптор наведения узлов, однако реализация метода drawImage в cytoscape-edgehandles 2.7.1 не ожидает загрузки изображения перед рисованием, поэтому возникает ошибка диапазона.

Я попытался дать графику Cytoscape параметры после загрузки изображения, однако график Cytoscape ожидает, что параметры будут немедленно доступны для использования. Так или иначе, мне нужно загрузить изображение, прежде чем передать его на график.

В конструкторе контроллера:

this.$scope.ehOptions = this.GetEhOptions();

Метод get EhOptions:

protected GetEhOptions(): GraphModels.EhOptions {
    var options = new GraphModels.EhOptions;

    var img = new Image();
    img.width = 25;
    img.height = 25
    img.src = "../../Content/icons/ic_circle_add_24px.svg";
    options.handleImage = img;
    img.addEventListener('load', e => {
          return options;
    });
}

Это приводит к тому, что опции никогда не загружаются графиком. Если я сделаю это вместо меня, я получу все опции, кроме изображения:

var options = new GraphModels.EhOptions;

var img = new Image();
img.width = 25;
img.height = 25
img.src = "../../Content/icons/ic_circle_add_24px.svg";

img.addEventListener('load', e => {
   options.handleImage = img;
});
return options;

Код цитопробежек-указателей, касающихся handleIcon:

if(options().handleIcon){
    var icon = options().handleIcon;
    var width = icon.width*cy.zoom(), height = icon.height*cy.zoom();
    ctx.drawImage(icon, hx-(width/2), hy-(height/2), width, height);
}

Если он изменен наэто, тогда это работает:

if (true) {
    var img = new Image();
    var width = 25 * cy.zoom();
    var height = 25 * cy.zoom();
    img.width = width;
    img.height = height
    img.src = "../../Content/icons/ic_circle_add_24px.svg";
    img.addEventListener('load', e => {
        ctx.drawImage(img, hx - (width/2), hy - (height/2), width, height)
    })
}

Однако я не могу изменить код библиотеки.

Надеюсь, у вас есть какие-либо идеи. Спасибо!

Ответы [ 3 ]

0 голосов
/ 15 ноября 2019

Нет опыта работы с конкретной библиотекой, но я работал с похожими. В этих случаях я включил его в свою собственную директиву, а затем напрямую контролировал создание. В этом случае у вас есть доступ к элементу $, и вы можете создать его на лету.

0 голосов
/ 15 ноября 2019

Создание обещания AngularJS:

protected GetEhOptions(): GraphModels.EhOptions {

    var deferred = $q.defer();
    var options = new GraphModels.EhOptions;           
    var img = new Image();

    img.width = 25;
    img.height = 25
    img.src = "../../Content/icons/ic_circle_add_24px.svg";
    options.handleImage = img;
    img.addEventListener('load', e => {
         ̶r̶e̶t̶u̶r̶n̶ ̶o̶p̶t̶i̶o̶n̶s̶;̶
         deferred.resolve(options);
    });
    img.addEventListener('error', e => {
         deferred.reject(e);
    });

    return deferred.promise;
}

Затем извлеките параметры из возвращенного обещания:

this.GetEhOptions().then(options => {
  this.$scope.ehOptions = options;
});

Для получения дополнительной информации см.

0 голосов
/ 15 ноября 2019

Я не имею никакого представления о cytoscape, но попробуйте это,

options:any = new GraphModels.EhOptions;
let globleThis = this;

var img = new Image();
img.width = 25;
img.height = 25
img.src = "../../Content/icons/ic_circle_add_24px.svg";
this.options.handleImage = img;

img.addEventListener('load', e => {
   this.GetEhOptions(globleThis.options);
});

protected GetEhOptions(options): GraphModels.EhOptions {
   return options;
}

или

var options = new GraphModels.EhOptions;

var img = new Image();
img.width = 25;
img.height = 25
img.src = "../../Content/icons/ic_circle_add_24px.svg";

img.addEventListener('load', e => {
   return options.handleImage = img;
});
...