2013-08-16 4 views
0

Я хотел бы иметь возможность запускать функцию, объявленную в моей переменной «Таблица». Причина заключается в том, чтобы избежать строки синтаксического анализа на основе запустить функцию ...Вызвать функцию, объявленную внутри переменной параметром

 var Table = function(params){ 
      var rowTemplate = params.rowTemplate; 
      var table = params.table; 

      function GetRow() 
      { 
       return $(rowTemplate).html(); 
      } 

      function AddRow() 
      { 
       $(table).append(GetRow()); 
      } 

      function BindEvents() 
      {  
       for(a in params.bind) 
       { 
        params.bind[ a ].action(); 
       } 
      } 

      function Construct() 
      { 
       BindEvents(); 
      } 

      Construct(); 

      return { 
       AddRow: function() { AddRow(); } 
      } 
     }; 

     var ProductsTable = new Table({ 
      table: "#ProductsTable tbody", 
      rowTemplate: "#ProductsTable_TemplateRow", 
      bind: [ 
       { action: AddRow, element: "#productsAddRowButton" } 
      ] 
     }); 

Вы можете видеть, что мой ProductsTable переходит в мой конструкт объект со свойством называется «привязывать», который представляет собой массив действий и элемент, который их создает.

AddRow, очевидно, еще не объявлен. поэтому он выдает ошибку. То, что я не хочу делать, это передать строку «AddRow», потому что тогда я буду разбирать строку ... затем запустить функцию из области «Таблица», и это уродливо.

Любые решения для этого?

Вот мое решение, благодаря ответу «Нет, это не может быть сделано», которые ставят меня на след заявление переключателя :(... :):

 var Table = function(params){ 
      var rowTemplate = params.rowTemplate; 
      var table = params.table; 

      function GetRow() 
      { 
       return $(rowTemplate).html(); 
      } 

      function AddRow() 
      { 
       $(table).append(GetRow()); 
      } 

      function BindEvents() 
      {  
       for(a in params.bind) 
       { 
        switch(params.bind[ a ].action) 
        { 
         case "AddRow":  
          $(params.bind[ a ].element).click(function(){ 
           AddRow(); 
          }); 
         break; 
        } 
       } 
      } 

      function Construct() 
      { 
       BindEvents(); 
      } 

      Construct(); 

      return { 
       AddRow: function() { AddRow(); } 
      } 
     }; 

     var ProductsTable = new Table({ 
      table: "#ProductsTable tbody", 
      rowTemplate: "#ProductsTable_TemplateRow", 
      bind: [ 
       { action: "AddRow", element: "#productsAddRowButton" } 
      ] 
     }); 
+0

Ого, это много ненужных объявлений функций ... Просто вставьте их! – Bergi

+0

Я не понимаю, что должно делать 'bindEvents'. Он просто выполняет набор заданных функций, но без какого-либо дополнительного контекста - что он должен делать с таблицей? Вы можете передать пустой массив и просто выполнить 'ProductsTable.AddRow()' впоследствии. – Bergi

+0

Что объявляет функции, которые вы хотите привязать в масштабе области? Вы могли бы связать их, если бы они были объявлены снаружи. –

ответ

0

Я не подумайте, что вы можете обойти имена функций как строки, поскольку фактические функции не существуют до тех пор, пока объект не будет создан.

Даже передача их в виде строк, кажется, имеет проблемы из-за обзора. Так что это так, что я хотел бы сделать это:

var Table = function(params){ 
    var rowTemplate = params.rowTemplate; 
    var table = params.table; 
    // add any additional functions to this object 
    var functions = { 
     AddRow: function() { 
      $(table).append(GetRow()); 
     } 
    }; 

    function GetRow() 
    { 
     return $(rowTemplate).html(); 
    } 

    function BindEvents() 
    {  
     for(var a in params.bind) 
     { 
      var action = params.bind[a].action; 
      if (functions.hasOwnProperty(action)) { 
       functions[action](); 
      } 
     } 
    } 

    BindEvents(); 
}; 

var ProductsTable = new Table({ 
    table: "#ProductsTable tbody", 
    rowTemplate: "#ProductsTable_TemplateRow", 
    bind: [ 
     { action: "AddRow", element: "#productsAddRowButton" } 
    ] 
}); 

Передача имен функций в качестве строки используется довольно часто в JavaScript, так что я не был бы обеспокоен делать это таким образом.

Пример - http://jsfiddle.net/4uxAX/

+0

Области обзора в порядке, у меня есть перегрузка AddRow, объявленная публично и конфиденциально для области переменных. но да, если вы говорите, что я не могу передать ему ссылку (что делает абсолютный смысл), тогда я сделаю переход на этого плохого мальчика. Я мог бы даже поставить некоторые битфлаги/маски, должен сделать для некоторого более аккуратного кода! – Jimmyt1988

+0

Перегрузка AddRow действительно работает нормально, поскольку доступ к ней публично! Таким образом, моя кнопка с определенным событием клика запускает личную версию AddRow .., но затем я могу использовать свою публичную функцию для запуска AddRow! если я хочу назвать его программным, а не основанным на событиях. Cest parfait. Если я объявил AddRow с this.AddRow = function, мне пришлось бы создать дескриптор области для моих функций jquery click, поэтому это работает очень хорошо! – Jimmyt1988

0

Это выстрел в темноте, но я предполагаю, что ваш фактический код не ссылаться на bind действий синхронно из конструктора. Если они, например, связанные с событиями, то вы можете просто использовать закрытие, чтобы описать методы, которые еще не созданы:

var ProductsTable = new Table({ 
    table: "#ProductsTable tbody", 
    rowTemplate: "#ProductsTable_TemplateRow", 
    bind: [ 
     { 
      action: function() { 
       ProductsTable.AddRow(); 
      }, 
      element: "#productsAddRowButton" 
     } 
    ] 
}); 
Смежные вопросы