Ich habe eine Direktive, die einen eigenen Controller hat. Siehe den folgenden Code:
var popdown = angular.module('xModules',[]);
popdown.directive('popdown', function () {
var PopdownController = function ($scope) {
this.scope = $scope;
}
PopdownController.prototype = {
show:function (message, type) {
this.scope.message = message;
this.scope.type = type;
},
hide:function () {
this.scope.message = '';
this.scope.type = '';
}
}
var linkFn = function (scope, lElement, attrs, controller) {
};
return {
controller: PopdownController,
link: linkFn,
replace: true,
templateUrl: './partials/modules/popdown.html'
}
});
Dies soll ein Benachrichtigungssystem für Fehler / Benachrichtigungen / Warnungen sein. Ich möchte von einer anderen Steuerung (keine Direktive) die Funktion show
auf dieser Steuerung aufrufen . Und wenn ich das mache, möchte ich auch, dass meine Link-Funktion erkennt, dass sich einige Eigenschaften geändert haben, und einige Animationen ausführt.
Hier ist ein Code, der veranschaulicht, wonach ich frage:
var app = angular.module('app', ['RestService']);
app.controller('IndexController', function($scope, RestService) {
var result = RestService.query();
if(result.error) {
popdown.notify(error.message, 'error');
}
});
Wenn Sie also show
den popdown
Direktiven-Controller aufrufen , sollte auch die Link-Funktion ausgelöst werden und eine Animation ausführen. Wie könnte ich das erreichen?
javascript
jquery
angularjs
angularjs-directive
user253530
quelle
quelle
popdown
Direktive auf der Seite auf - befindet sich nur an einer Stelle, an der alle anderen Controller Zugriff darauf haben sollen, oder gibt es mehrere Popdowns an verschiedenen Stellen?popdown.show(...)
anstattpopdown.notify(...)
ist das richtig? Ansonsten ist die Benachrichtigungsfunktion etwas verwirrend.popdown.notify
?.notifiy
Methode, ich meineAntworten:
Dies ist eine interessante Frage, und ich begann darüber nachzudenken, wie ich so etwas implementieren würde.
Ich habe mir das ausgedacht (Geige) ;
Anstatt zu versuchen, eine Direktive von einem Controller aufzurufen, habe ich ein Modul erstellt, in dem die gesamte Popdown-Logik untergebracht ist:
Ich habe zwei Dinge in das Modul eingefügt , eine
factory
für die API, die überalldirective
eingefügt werden kann, und die für die Definition des Verhaltens des tatsächlichen Popdown-Elements:Die Fabrik definiert nur ein paar Funktionen
success
underror
und verfolgt die Spuren von ein paar Variablen:Die Direktive ruft die API in ihren Controller ein und überwacht die API auf Änderungen (ich verwende zur Vereinfachung Bootstrap-CSS):
Dann definiere ich ein
app
Modul, das abhängt vonPopdown
:Und der HTML sieht aus wie:
Ich bin mir nicht sicher, ob es völlig ideal ist, aber es schien ein vernünftiger Weg zu sein, die Kommunikation mit einer globalen Popdown-Direktive einzurichten.
Wieder als Referenz die Geige .
quelle
success(msg)
das HTML aufzurufensucess(name, msg)
, würden Sie aufrufen , um die Direktive mit dem richtigen Namen auszuwählen.Sie können auch Ereignisse verwenden, um den Popdown auszulösen.
Hier ist eine Geige, die auf der Lösung von Satchmorun basiert. Es verzichtet auf die PopdownAPI und die Controller der obersten Ebene stattdessen auf
$broadcast
die Ereignisse "Erfolg" und "Fehler" in der gesamten Bereichskette:Das Popdown-Modul registriert dann Handlerfunktionen für diese Ereignisse, z.
Dies funktioniert zumindest und scheint mir eine gut entkoppelte Lösung zu sein. Ich werde andere einschalten lassen, wenn dies aus irgendeinem Grund als schlechte Praxis angesehen wird.
quelle
Sie können den Controller der Direktive auch dem übergeordneten Bereich aussetzen, wie dies
ngForm
beiname
Attributen der Fall ist: http://docs.angularjs.org/api/ng.directive:ngFormHier finden Sie ein sehr einfaches Beispiel, wie dies erreicht werden kann: http://plnkr.co/edit/Ps8OXrfpnePFvvdFgYJf?p=preview
In diesem Beispiel habe ich
myDirective
mit dediziertem Controller mit$clear
Methode (eine Art sehr einfache öffentliche API für die Direktive). Ich kann diesen Controller im übergeordneten Bereich veröffentlichen und diese Methode außerhalb der Direktive aufrufen.quelle
$scope.$parent[alias]
es immer noch nicht gern, weil es für mich nach innerer eckiger API riecht. Aber ich kann immer noch keine elegantere Lösung für Nicht-Singleton-Direktiven finden. Andere Varianten wie das Senden von Ereignissen oder das Definieren eines leeren Objekts im übergeordneten Controller für Direktiven-API riechen noch mehr.Ich habe eine viel bessere Lösung.
Hier ist meine Direktive, ich habe die Objektreferenz in die Direktive eingefügt und diese durch Hinzufügen einer Aufruffunktion im Direktivencode erweitert.
Deklarieren der Direktive im HTML mit einem Parameter:
mein Controller:
quelle