2016-04-18 6 views
1

Ich habe eine einfache Richtlinie external-link verursacht die Verbindung, in der sie platziert wird die URL in einem separaten Fenster zu öffnen statt der aktuellenAngularJS + ui.router: unterschiedliches Verhalten zwischen Richtlinie Controller und Verknüpfungsfunktionen

<a app-external-link href="http://example.com">Example</a> 

es ist wie target="_blank" aber mit der Fähigkeit, wenn Benutzer darauf klicken zu verfolgen

aus Gründen des Beispiels mir die Tracking-Funktion entfernt, so dass es nur wie das target=_blank Attribut verhalten hat

angular.module('app', []) 
.directive('appExternalLink', function ($window) { 
    var link = function (scope, element, attrs) { 
    element.on('click', function (event) { 
     event.preventDefault(); 
     $window.open(attrs.href, '_blank'); 
    }); 
    }; 

    return { 
    scope: true, 
    link: link 
    }; 
}); 

Diese Implementierung funktioniert wie erwartet. Was ich überraschte, ist, dass in meinem ersten Ansatz war ich Richtlinie des Controller:

angular.module('app', []) 
.directive('appExternalLink', function ($window) { 
    var controller = function ($element, $attrs) { 
    $element.on('click', function (event) { 
     event.preventDefault(); 
     $window.open($attrs.href, '_blank'); 
    }); 
    }; 

    return { 
    scope: true, 
    controller: controller 
    }; 
}); 

Ich verstehe nicht, warum (daher diese Frage) in der Richtlinie Controller Beispiel die Verbindung erfolgreich in einem neuen Fenster öffnet, aber es ändert sich auch die aktuelle Ansicht auf die neue uRL

es ist, als ob event.preventDefault() tut nichts in diesem Fall

Alle Ideen, warum dies geschieht?

Update:

Das Problem tritt nur auf, wenn die Richtlinie mit ui-sref

<a app-external-link ui-sref="foo">Example</a> 

Plunk here

+0

Welche Version von eckigen? – CShark

+0

Ich habe mich gefragt, weil ich Ihr Problem nicht reproduzieren konnte, ohne "preventDefault" zu entfernen. Wenn Sie 'href' leer lassen und die URL nur aus einem anderen Attribut in Ihre Anweisung übergeben, müssen Sie nicht einmal' preventDefault' verwenden, da [angular handys this] (https://docs.angularjs.org/ api/ng/directive/a), seit es "Ändert das Standardverhalten des HTML-Tags, so dass die Standardaktion verhindert wird, wenn das href-Attribut leer ist" – CShark

+0

@CShark Ich benutze Version 1.5.3 Ich kann Wiederhole es nicht in einem Plunk, aber ich mache es in meinem Projekt. Also muss ich das Problem näher betrachten. Der alternative Attributansatz ist ebenfalls eine gute Idee. Danke! –

Antwort

0

Ich habe 2 mögliche Lösungen verwendet wird.

  1. Verwendung event.stopImmediatePropagation() in Kombination mit event.preventDefault() für den Click-Handler in den controller als auch die aktuelle Seite URL ändert zu stoppen.

    Demo: http://plnkr.co/edit/6Qi8NcWMmOvC4R3ZAqsf?p=info

  2. ui-sref bereits mit target="_blank" funktioniert, so haben Sie Ihre Richtlinie an das Element dieses Attribut nur hinzufügen, und dann tun, was Sie in Ihrem Click-Handler tun wollen, ohne selbst zu kümmern Umgang mit der Veranstaltung oder mit window.open.

    element.attr('target', '_blank'); 
    element.on('click', function (event) { 
        //can track clicks or do whatever you want here 
        console.log(attrs.href + ' opened in new tab.'); 
    }); 
    

    Demo: http://plnkr.co/edit/brvftLiqXLznS6IWNmVA?p=info

Ich ziehe wegen der Gründe, warum ich aufgelistet und weil es weniger Code ist und es lässt angular und ui-router ihre Arbeit tun getrennt von dem, was Sie versuchen, zu tun (anstatt etwas Logik etwas zu duplizieren). Außerdem habe ich nicht wirklich alles sehr viel getestet und es könnte sich auf andere Dinge auswirken, die ich noch nicht gesehen habe.Es scheint jedoch zu funktionieren, wenn Sie es lieber so machen würden.

+0

** Ansatz 2 ** ist sauber und löst das Problem. Danke! –

Verwandte Themen