在动态生成的元素上的提取请求内的jquery .val()方法

时间:2018-06-25 18:49:26

标签: javascript jquery ecmascript-6 fetch

我正在尝试创建一个可重用的函数,该函数将点击处理程序附加到一系列动态创建的元素上。这不是问题(我认为)。大多数单击处理程序都包含提取请求,这些请求的有效负载是一些用户输入。这是我想出的代码。当前,用户对象中电子邮件和密码的值都以未定义的形式在获取请求中提交。这是代码:

父函数:

const addEventHandlerTo = (child, endpoint, headers, method, cb, data) => {
console.log('this is firing from ' + child + ' with method ' + method + ' to ' + endpoint);
$(document).on('click', child, function(event){
  console.log(console.table(headers), console.table(data))
  console.log(child + ' fired off a fetch to ' + endpoint);
  event.preventDefault();
  event.stopImmediatePropagation();

  fetch(apiBaseUrl + endpoint, {
    method: method,
    headers: headers, 
    body: JSON.stringify(data),
  })
  .then(response => {
    if (!response.ok) {
      Promise.reject(response.statusText);
    } return response.json();
  })
  .then(somethings => {
    console.log(somethings)
    cb(somethings);
  })
  .catch(err => console.error(err));
})

这是用于发送获取请求的登录按钮的事件处理程序:

addEventHandlerTo(
    '#login-button',
    'signin',
    {
      'Content-Type': 'application/json',
      'Authorization': 'Bearer ' + token()
    },
    'POST',
    setTokenAndRedirect, //TODO redirect
    {'user': {
      'email': $('#login-password').val(),
      'password': $('#login-password').val()
    }}
  )

这是我到目前为止所做的:

  1. 三重检查ID是否与端点匹配
  2. 尝试将电子邮件值传递为:getEmail(),其中

    getEmail = () => {$(document).find('#login-email')

  3. 将伪字符串硬编码到请求中(效果很好)。

我很乐意指出正确的方向。我觉得原因是关于动态添加的单击处理程序,我没有正确利用事件委托(我可能不应该将jQuery函数放在请求中……?)。但是,在过去的几个小时中,我的大脑已经解决了这个问题,我无法弄清楚为什么我不应该这样做,以及解决方案是什么(理想情况下,可以保持父函数的结构) 。

在此先感谢您的帮助。让我知道您是否需要更多信息:)

1 个答案:

答案 0 :(得分:1)

我对jQuery有点生疏,但我认为这里的问题更多是在执行时设置每个部分,而不是使用所使用的库进行任何设置。在定义处理程序时,两个主体值是未定义的,您需要传入处理程序。我将研究抽象该方法的其他部分,也许是这样的:

const makeRequest = ({endpoint, method, headers, body}) => {
  const baseUrl = 'www.example.com';
  const uri = new URL(endpoint, baseUrl);
  return fetch(uri, { method, headers, body })
    .then(response => (!response.ok) ? Promise.reject(response.statusText()) : response.json());
};

const handlerFactory = (fetchParams, callback, buildBody = null) => {
  return e => {
    e.preventDefault();
    e.stopImmediatePropagation();

    if (buildBody !== null) {
      fetchParams.body = JSON.stringify(buildBody());
    }

    return makeRequest(fetchParams)
      .then(callback)
      .catch(err => console.error(/*please make your errors human detectable*/ err));
  }
};

const getUser = () => ({
  user: {
    email: $('#login-password').val(),
    password: $('#login-password').val(),
  }
});

const addEventHandler = (parent, delegate, fetchParams, callback, buildBody) => {
  const handler = handlerFactory(fetchParams, callback, buildBody);
  $(parent).on('click', delegate, handler);
});

然后设置一个方法(您的登录示例):

let params = {
  endpoint: 'signin',
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer ' + token()
  },
  body: {},
}

addEventHandler('document', '#login-button', params, setTokenAndRedirect, getUser);

编辑

添加了我在第一遍错过的JSON.stringify()(记入下面的评论者:))