Как запустить функцию в объекте javascript программно? - PullRequest
0 голосов
/ 08 января 2020

Я пытаюсь создать пользовательский запрос с Dex ie, где пользователь запрашивает базу данных самостоятельно, но я не могу заставить ее работать.

<!-- html -->

<div class="window" style="padding-top: 1.5rem;">
<link rel="stylesheet" type="text/css" href="./css/bootstrap-grid.min.css">
 <div class="window-content">
   <div class="pane-group">
       <div class="pane" style="padding:4rem;padding-top: 0 ">
           <h3 class="text-center"><u><span class="icon icon icon-code icon-text" style="color:#4e5851;padding-right:1rem "></span>Advanced Queries</u></h3>
           <table class="table-striped mb-2">
               <thead>
               <tr>
                   <th colspan="3"><input class="form-control" type="" name="query" id="query"></th>
                   <th style="width:4rem"><button class="btn btn-default" id="run">
                       <span class="icon icon-search"></span>
                   </button></th>
               </tr>
           </thead>
           </table>
           <div class ="row" style="display: flex" id='display_body'>

           </div>
       </div>
   </div>
</div>
</div>

//script

document.querySelector('#run').addEventListener("click", function(){
const { init_data} = require('../res/reusable');
var db = init_data(Dexie);
let torun = document.querySelector('#query').value; 
let mangoArray=torun.split('.')
//console.log('mangoArray');
if (mangoArray.length== '1') {
    db[mangoArray[0]].each(item=>{
        console.log(item);
});

}else if(mangoArray.length== '2'){
db[mangoArray[0]][mongoArray[1]].each(item=>{
console.log(item);
});
}
});

Когда я ввожу devices во ввод (таблица в базе данных dex ie работает) в полном объеме должна запускаться db.devices.each

Однако я не могу заставить функции работать внутри класса dex ie. поэтому при вводе devices.orderBy('name') я получаю неопределенную ошибку

//error
Uncaught TypeError: Cannot read property 'each' of undefined

Как мне этого добиться?

1 Ответ

1 голос
/ 08 января 2020

Прежде всего, то, что вы пытаетесь сделать, довольно опасно; предоставляя пользователю возможность выполнить произвольный запрос к базе данных из внешнего интерфейса вашего приложения. Я советую осторожно.

Во-вторых, ошибка говорит само за себя - вы не можете вызвать метод each() для undefined. Что такое undefined тогда? Видите, когда ваш запрос выглядит следующим образом: devices.orderBy('name'), код выполняет следующее:

let mangoArray=torun.split('.') // ["devices", "orderBy('name')"]
...
}else if(mangoArray.length== '2'){
db[mangoArray[0]][mongoArray[1]]
// ^ now pay attention: db["devices"]["orderBy('name')"]
.each(item=>{
  console.log(item);
});

Итак, хотя объект db имеет поле атрибута devices, он определенно не имеет orderBy('name'). Если вы хотите вызвать метод этого объекта, есть несколько способов справиться с этим. Самый простой (но самый опасный ) - пропустить разделение и обработать его с помощью eval:

const query = eval(`db.${torun}`)
query.each(...)

Но это позволяет пользователю делать с вашими данными все, что он хочет - удалить, изменить, испортить и т. д. c. Более безопасный способ - использовать довольно сложную проверку регулярных выражений на входе.

Самым безопасным и наиболее рекомендуемым является создание удобного интерфейса, позволяющего пользователю получить доступ к вашим данным с полным контроль. Создайте несколько форм, которые позволяют пользователю выбирать, какие данные он хочет получить, как их упорядочить, фильтровать, затем отправлять эти данные через сервер и возвращать адекватный ответ. Это называется «скрытой реализацией» - пользователю вашего приложения не нужно знать, какую базу данных вы используете, не говоря уже об API этой базы данных!

Надеюсь, это поможет.

...