2014-05-13 9 views
17

Sto utilizzando Angular & Bootstrap, con il controllo della scheda di navigazione per cambiare la visibilità delle div. In un div, ho una grande img (disegno CAD dell'edificio). Inoltre, sovrapposto i marcatori sull'immagine. Voglio ridimensionare la posizione x/y dei marcatori in base alla larghezza dell'immagine & immagine naturalWidth. Sto usando una direttiva di ridimensionamento per rilevare le modifiche e aggiornare il mio ambito.Come attivare l'evento di ridimensionamento in AngularJS

Il mio problema è che se l'utente cambia scheda e passa di nuovo a div con CAD img, l'aggiornamento non avviene finché non ridimensiono il browser (o sorprendentemente se premo il tasto CMD su Mac).

C'è un modo angolare per attivare l'evento di ridimensionamento per forzare il ricalcolo dei miei indicatori. O c'è un evento che posso attingere che viene attivato quando viene visualizzato completamente?

O c'è un approccio angolare più raffinato che dovrei prendere?

Questo è l'HTML, la direttiva di ridimensionamento che ho scritto è sul tag.

<div id="imageDiv" style="position: relative;" ng-show="selectedLocation" > 
    <img ng-src="../maps/image/{{selectedLocation}}" 
     style=" max-width: 100%; max-height: auto; border:solid 1px black" resize imageonload /> 
</div> 

E questa è la direttiva di ridimensionamento (adattato da http://jsfiddle.net/jaredwilli/SfJ8c/)

directive('resize', function($window) { 
    return function(scope, element) { 
    var w = angular.element($window); 

    scope.imgCadImage = element; 

    scope.getWindowDimensions = function() { 
     return { 
     'h' : scope.imgCadImage[0].width, 
     'w' : scope.imgCadImage[0].height 
     }; 
    }; 
    scope.$watch(scope.getWindowDimensions, function(newValue, oldValue) { 
     if (scope.imgCadImage[0].naturalWidth) 
     scope.imgScale = newValue.w/scope.imgCadImage[0].naturalWidth; 
     else 
     scope.imgScale = 1; 
     console.log("watched resize event - scale = "+scope.imgScale) 
     scope.updateCADMarkersAfterResize(); 
    }, true); 
    w.bind('resize', function() { 
     console.log("'resize' - scale = "+scope.imgScale) 
     scope.$apply(); 
    }); 
    }; 
}). 
+0

Hai provato l'aggiunta di un attributo basato direttiva comportamentale per il div che contiene il immagine che chiama il ridimensionamento nella sua funzione 'link'? –

+0

@MarcKline - qual è la funzione di collegamento div? Puoi indicarmi qualche altra informazione a riguardo. La ricerca su Google non è di grande aiuto. – Kevin

+0

Permettetemi innanzitutto di chiedervi questo: la vostra direttiva resize a) è allegata all'immagine o al suo contenitore eb) è vincolata/attivata solo dall'evento 'window.resize'? Sarebbe molto utile se potessi fornire qualche pseudocodice che mostri quello che hai descritto, ma se puoi rispondere a queste domande potrei essere in grado di indovinare una soluzione. –

risposta

10

Prova iniettando $timeout nella direttiva resize:

directive('resize', function($window, $timeout) { 

... quindi aggiungere la seguente riga alla fondo:

$timeout(function(){ w.triggerHandler('resize') }); 

Questo dovrebbe attivare il gestore che è stato associato a $window.resize subito dopo il rendering del browser.

+1

Questo ha fatto il trucco, grazie. Ho anche dovuto aggiungere la chiamata a $ timeout (function() {w.triggerHandler ('ridimensiona')}); nelle aree in cui cambio anche il controllo delle schede. – Kevin

+1

lieve trucco: 'triggerHandler' attiva solo gli eventi aggiunti da jqLite/jQuery. Se il tuo evento viene aggiunto con javascript puro (ad esempio 'addEventListener'), sei SOL. Vedi [questa domanda] (http://stackoverflow.com/questions/34804800/angularjs-doesnt-trigger-event-handled-by-addeventlistener) e [questa domanda] (http://stackoverflow.com/questions/2490825/ how-to-trigger-event-in-javascript) per maggiori informazioni. – adamdport

2

La risposta accettata non ha funzionato per me - w è indefinito.

Questo fatto:

$timeout(function(){ 
    $(window).trigger('resize'); 
}); 
+0

$ (finestra) .trigger ('ridimensiona') non è la modalità AngularJS. – VicJordan

12

questo ha lavorato per me quando il di cui sopra non ha fatto.

$timeout(function() { 
    $window.dispatchEvent(new Event("resize")); 
}, 100); 

ho dovuto usare anche $timeout con un ritardo nel mio caso per evitare errori di circa digerire cicli già essere in corso. Non tutti i casi d'uso potrebbero aver bisogno di questo.

dispatchEvent è ben supportato http://caniuse.com/#feat=dispatchevent

Tuttavia, è necessario IE9 e IE10 supporto si dovrà usare il loro metodo propritary: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/fireEvent

+1

Questo fa il trucco. – vinitius

+0

utilizzando un ritardo di timeout> 0 in questo scenario è quasi certamente una cattiva idea. > I timeout 0 non dovrebbero essere usati per risolvere i problemi di temporizzazione, dovrebbero essere usati solo quando in realtà vuoi che qualcosa accada in quel tempo (ad esempio un'animazione). Non hai assolutamente alcuna garanzia che 100ms siano la quantità appropriata di tempo per evitare problemi di temporizzazione su qualsiasi dispositivo. – tomfumb

+0

Ha lavorato per me senza ritardi, mettendo il timeout lì solo lo forza sul prossimo ciclo di digest –

Problemi correlati