javascript - jquery .val() 方法在动态生成的元素上获取请求

标签 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. 将虚拟字符串硬编码到请求中(效果很好)。

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

非常感谢您的帮助。如果您需要更多信息,请告诉我:)

最佳答案

我对 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()(归功于下面的评论者:))

关于javascript - jquery .val() 方法在动态生成的元素上获取请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51030083/

相关文章:

javascript - 根据键值的存在从数组中删除元素

javascript - Strapi Beta (3.0) 的自定义 Controller 代码

javascript - 在 Typescript/React 应用程序中找不到 'node' 的类型定义文件

javascript - jQuery:html() 在事件中不可用?

javascript - 带有自定义进度条的 JQuery 文件上传 (blueimp)

javascript - 如何按 ID 减去特定列值并在所有行的另一列中显示结果?

基于先前值的 Javascript 过滤器

javascript - Angular/javascript 中的 int 到标志枚举

php - Web 应用程序 HTML 参数传递

javascript - 根据用户输入的内容创建数组