Jak mogę wywołać funkcję zdefiniowaną w kontrolerze z dowolnego miejsca strony internetowej (poza komponentem kontrolera)?
Działa idealnie po naciśnięciu przycisku „pobierz”. Ale muszę to nazwać spoza kontrolera div. Logika brzmi: domyślnie mój div jest ukryty. Gdzieś w menu nawigacyjnym wciskam przycisk, który powinien pokazać () mój div i uruchomić funkcję „get”. Jak mogę to osiągnąć?
Moja strona to:
<div ng-controller="MyController">
<input type="text" ng-model="data.firstname" required>
<input type='text' ng-model="data.lastname" required>
<form ng-submit="update()"><input type="submit" value="update"></form>
<form ng-submit="get()"><input type="submit" value="get"></form>
</div>
Mój js:
function MyController($scope) {
// default data and structure
$scope.data = {
"firstname" : "Nicolas",
"lastname" : "Cage"
};
$scope.get = function() {
$.ajax({
url: "/php/get_data.php?",
type: "POST",
timeout: 10000, // 10 seconds for getting result, otherwise error.
error:function() { alert("Temporary error. Please try again...");},
complete: function(){ $.unblockUI();},
beforeSend: function(){ $.blockUI()},
success: function(data){
json_answer = eval('(' + data + ')');
if (json_answer){
$scope.$apply(function () {
$scope.data = json_answer;
});
}
}
});
};
$scope.update = function() {
$.ajax({
url: "/php/update_data.php?",
type: "POST",
data: $scope.data,
timeout: 10000, // 10 seconds for getting result, otherwise error.
error:function() { alert("Temporary error. Please try again...");},
complete: function(){ $.unblockUI();},
beforeSend: function(){ $.blockUI()},
success: function(data){ }
});
};
}
get()
MyController z innego kontrolera?Odpowiedzi:
Oto sposób na wywołanie funkcji kontrolera spoza niej:
gdzie
get()
jest funkcja z twojego kontrolera.Możesz zmienić
do
Jeśli używasz jQuery.
Ponadto, jeśli twoja funkcja oznacza zmianę czegokolwiek w twoim Widoku, powinieneś zadzwonić
zastosować zmiany.
Jeszcze jedną rzeczą, na którą należy zwrócić uwagę, że zakresy są inicjowane po załadowaniu strony, więc metody wywoływania spoza zakresu powinny zawsze być wykonywane po załadowaniu strony. W przeciwnym razie w ogóle nie dojdziesz do zakresu.
AKTUALIZACJA:
Z najnowszymi wersjami angulara powinieneś używać
I tak, to jest w rzeczywistości zła praktyka , ale czasami potrzebujesz po prostu rzeczy wykonanych szybko i brudno.
źródło
$apply
części do pracy, dopóki nie zapakowałem kodu w funkcję, np...scope.$apply(function() { scope.get() });
angular.element(document.getElementById('yourControllerElementID')).scope().controller;
np. if use:angular.element(document.getElementById('controller')).scope().get()
zgłasza i nieokreślony błąd, ale jeśliangular.element(document.getElementById('controller')).scope().controller.get()
go używam , działa.scope()
wangular.element(...)
, ponieważ zwraca niezdefiniowane, a vardump elementu / obiektu kątowego mówi, że funkcjascope
znajduje się w obiekcie__proto__
-object.Znalazłem przykład w Internecie.
Jakiś facet napisał ten kod i działał doskonale
HTML
JAVASCRIPT
Próbny
* Dokonałem pewnych modyfikacji, patrz oryginał: czcionka JSfiddle
źródło
Rozwiązanie
angular.element(document.getElementById('ID')).scope().get()
przestało działać dla mnie w wersji kątowej 1.5.2. Sombody wspomina w komentarzu, że nie działa to również w 1.4.9. Naprawiłem to, przechowując zakres w zmiennej globalnej:zadzwoń z niestandardowego kodu:
jeśli chcesz ograniczyć zakres tylko do tej metody. Aby zminimalizować ekspozycję całego zakresu. użyj następującej techniki.
zadzwoń z niestandardowego kodu:
źródło
Odpowiedź Dmitry'ego działa dobrze. Właśnie zrobiłem prosty przykład przy użyciu tej samej techniki.
jsfiddle: http://jsfiddle.net/o895a8n8/5/
.
źródło
Wolę uwzględnić fabrykę jako zależności od kontrolerów, niż wstrzyknąć im własną linię kodu: http://jsfiddle.net/XqDxG/550/
ControllerZero. $ Inject = ['$ scope', 'mySharedService'];źródło
Warto rozważyć, czy posiadanie menu bez powiązanego zakresu jest właściwą drogą. To naprawdę nie jest kątowy sposób.
Ale jeśli jest to sposób, w jaki musisz iść, możesz to zrobić, dodając funkcje do $ rootScope, a następnie w obrębie tych funkcji, używając $ broadcast do wysyłania zdarzeń. kontroler używa $ on do nasłuchiwania tych zdarzeń.
Inną rzeczą do rozważenia, jeśli ostatecznie skończysz z menu bez zakresu, jest to, że jeśli masz wiele tras, wszystkie kontrolery będą musiały mieć własną aktualizację i uzyskać funkcje. (przy założeniu, że masz wielu kontrolerów)
źródło
Używam do pracy z $ http, gdy chcę uzyskać informacje z zasobu, wykonuję następujące czynności:
I kod w kontrolerze:
Przesyłam do serwisu, jakie funkcje mają wywołać w kontrolerze
źródło
Mam wiele tras i wiele kontrolerów, więc nie mogłem uzyskać akceptowanej odpowiedzi do pracy. Odkryłem, że dodanie funkcji do okna działa:
Następnie poza kontrolerem można to zrobić:
źródło
Wywołaj funkcję zakresu kątowego spoza kontrolera.
źródło
Jestem użytkownikiem frameworka Ionic i znalazłem, który konsekwentnie zapewnia zakres $ bieżącego kontrolera:
angular.element(document.querySelector('ion-view[nav-view="active"]')).scope()
Podejrzewam, że można to zmodyfikować, aby pasowało do większości scenariuszy niezależnie od frameworka (lub nie), znajdując zapytanie, które będzie kierowane do określonych elementów DOM, które są dostępne tylko podczas danej instancji kontrolera.
źródło