2009-06-09 10 views
65

Pracuję nad dynamicznym tworzeniem kodu JavaScript, który zostanie wstawiony do strony internetowej podczas jej tworzenia.Jak wywołać metodę dynamicznie nazwaną w JavaScript?

Kod JavaScript zostanie użyty do zapełnienia pola listy na podstawie zaznaczenia w innym polu listy. Gdy zmieni się wybór jednego pola listy, wywoła nazwę metody na podstawie wybranej wartości pola listy.

Na przykład

Listbox1 zawiera:

kolory
Kształty

Jeżeli wybrano 'kolorów' to będzie nazwać "populate_Colours" metodę zapełnia inną listą.
Aby wyjaśnić moje pytanie: jak wykonać wywołanie "populate_Colours" w JavaScript?

+0

I zalecam odradzanie tego na rzecz posiadania oddziałów lokalnych w jednej metodzie "zaludnienia". Sprawiłoby, że byłaby bardziej testowalna i wyglądała mniej "hacky". –

+0

zobacz moją odpowiedź tutaj. [zadzwoń po imieniu w javascript] (https://stackoverflow.com/a/46090820/7771019) –

Odpowiedz

142

Zakładając, że metoda "populate_Colours" znajduje się w globalnej przestrzeni nazw, możesz użyć następującego kodu, który wykorzystuje zarówno właściwości wszystkich obiektów, jak i obiekty, które były asocjacyjną tablicą oraz, że wszystkie obiekty globalne są rzeczywistymi właściwościami. obiektu hosta window.

var method_name = "Colours"; 
var method_prefix = "populate_"; 

// Call function: 
window[method_prefix + method_name](arg1, arg2); 
+6

Dzięki za odpowiedź. "Okno" trochę mnie rzuciło, dopóki go nie wylogowałem i okazało się, że obiekty globalne są częścią obiektu okna. Teraz to ma sens! Dziękuję Ci. FYI Znalazłem dobrą stronę o tym tutaj http://devlicio.us/blogs/sergio_pereira/archive/2009/02/09/javascript-5-ways-to-call-a-function.aspx –

+0

Cieszę się, że pomógł! Powinieneś zaakceptować tę odpowiedź, jeśli ci się udało – Triptych

+0

Zrobiłem coś podobnego poza tym, że funkcje, na które celowałem, znajdowały się w przestrzeni nazw "fn" jQuery. Na przykład '$ .fn [method_prefix + nazwa_metody] (arg1, arg2);' – codecraig

27

Tryptyk Jak zaznacza, można wywołać dowolną funkcję globalnego scope przez znalezienie go w zawartości obiektu hosta.

Czystsze metoda, która zanieczyszcza globalnej przestrzeni nazw znacznie mniej, jest jawnie umieścić funkcje do tablicy bezpośrednio tak:

var dyn_functions = []; 
dyn_functions['populate_Colours'] = function (arg1, arg2) { 
       // function body 
      }; 
dyn_functions['populate_Shapes'] = function (arg1, arg2) { 
       // function body 
      }; 
// calling one of the functions 
var result = dyn_functions['populate_Shapes'](1, 2); 
// this works as well due to the similarity between arrays and objects 
var result2 = dyn_functions.populate_Shapes(1, 2); 

Tablica ta może być również własnością jakiegoś przedmiotu innego niż globalna Obiekt hosta zbyt oznacza, że ​​można skutecznie utworzyć własną przestrzeń nazw, jak wiele bibliotek JS, takich jak jQuery zrobić. Przydaje się to w celu zmniejszenia konfliktów, jeśli uwzględnisz wiele oddzielnych bibliotek narzędziowych na tej samej stronie i (inne części twojego projektu pozwalają) może ułatwić ponowne użycie kodu na innych stronach.

Można również użyć obiektu jak tak, to jakie można znaleźć czystsze:

var dyn_functions = {}; 
dyn_functions.populate_Colours = function (arg1, arg2) { 
       // function body 
      }; 
dyn_functions['populate_Shapes'] = function (arg1, arg2) { 
       // function body 
      }; 
// calling one of the functions 
var result = dyn_functions.populate_Shapes(1, 2); 
// this works as well due to the similarity between arrays and objects 
var result2 = dyn_functions['populate_Shapes'](1, 2); 

Należy zauważyć, że zarówno z tablicy lub obiektu, można użyć metody ustalania lub dostępu do funkcji, a może oczywiście przechowuj tam również inne przedmioty. Możesz dodatkowo zredukować składnię obu metoda contant że nie jest to synamic za pomocą JS dosłownego zapisu tak:

var dyn_functions = { 
      populate_Colours:function (arg1, arg2) { 
       // function body 
      }; 
     , populate_Shapes:function (arg1, arg2) { 
       // function body 
      }; 
}; 

edit: oczywiście dla większych bloków funkcjonalność można rozszerzyć wyżej bardzo powszechne "wzorzec modułu", który jest popularnym sposobem enkapsulacji elementów kodu w zorganizowany sposób.

+0

To dobry sposób na utrzymanie go w czystości. Jak jednak nazwać tę metodę? Czy okno [dyn_functions ['populate_Colours'] (arg1, arg2) działa? –

+0

Odpowiadając na moje własne pytanie - Właśnie przetestowałem okno [dyn_functions ['populate_Colours'] (arg1, arg2)]; i rzeczywiście działa. –

+1

Nie potrzebujesz okna – epascarello

1

Hi spróbować,

var callback_function = new Function(functionName); 
callback_function(); 

będzie obsługiwać sama parametry.

+0

niezrealizowany błąd referencyjny - nazwa funkcji nie jest zdefiniowana – brianlmerritt

+0

@brianlmerritt należy zdefiniować wartość dla 'functionName' ... odpowiadający założył, że już to zdefiniowałeś. – GoldBishop

7

można zrobić to tak:

function MyClass() { 
    this.abc = function() { 
     alert("abc"); 
    } 
} 

var myObject = new MyClass(); 
myObject["abc"](); 
1

dla prostej funkcji JavaScript, możemy uży- teczność

var function_name='additionFunction'; 
var argMap={"name":"yogesh"}; 
var argArray=[{"name":"yogesh"}]; 

window[function_name](argMap); 

lub

window[function_name](argArray); 

lub

window[function_name](argMap,argArray); 

pod warunkiem, że istnieje tak zwana funkcja i ma takie parametry w rzeczywistej implementacji.

-1

Spróbuj z tym:

var fn_name = "Colours", 
fn = eval("populate_"+fn_name); 
fn(args1,argsN); 
+0

Jakie są konsekwencje używania tego wzoru? Czytałem, że funkcja 'eval' ma pewne dziwne efekty uboczne związane z jej użyciem. Ogólnie staram się trzymać z dala od tego, chyba że jest to ostatnia deska ratunku. – GoldBishop

3

Polecam NIE używać global/window/eval do tego celu.
Zamiast zrobić to w ten sposób:

zdefiniować wszystkie metody, jak właściwości Handler:

var Handler={}; 

Handler.application_run = function (name) { 
console.log(name) 
} 

obecnie nazywamy go jak ten

var somefunc = "application_run"; 
Handler[somefunc]('jerry'); 

wyjściowa: Jerry