【问题标题】:How to create an automated html input text field that will display values being fetched from an API?如何创建一个自动 html 输入文本字段来显示从 API 获取的值?
【发布时间】:2019-02-12 08:08:03
【问题描述】:

我想构建一个输入文本字段,单击该字段时将显示通过内容 API 获取的值列表。当代码到达 forEach 循环时,它似乎不起作用。它工作正常,直到 initArray。 forEach 循环似乎不起作用。我在 initArray 的 console.log 中看到了我的所有数据。

我错过了什么吗?

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8"/>
    <title> URL Builder </title>
    <link rel="stylesheet" href="https://contentful.github.io/ui-extensions-sdk/cf-extension.css">
		<script src="https://unpkg.com/contentful-ui-extensions-sdk@3"></script>
  </head>
  <body>
    <form id="urlSearchContainer">
      <div class="cf-form-field">
        <input list="urlDataList" type="search" placeholder="Type your url here..." id="urlBuilder" class="cf-form-input">
        <datalist id="urlDataList">
        </datalist>
      </div>     
    </form>
    
    <script>
      "use strict"
      
      window.contentfulExtension.init(function(api) {
        api.window.startAutoResizer();
        
        // Set variables
        var urlDataList = document.getElementById("urlDataList");
        var urlInput = document.getElementById("urlBuilder");
                     
        function getUrlData(){
        //api.space.getEntries({'content_type[ne]': 'page-MBH'})
          var urlDataArray = [];
          api.space.getEntries()
          .then(function (entries) {
          	entries.items.forEach(function (entry) {
              if(entry.fields.url){
                var urlData = entry.fields.url.en
                urlDataArray.push(urlData);
                //console.log('urldata', urlDataArray);
              }
        	})
        })
          return urlDataArray;
        };
                
        function createUrlDropdown(){
          
          // Init data obj
          var data = getUrlData();
          var initArray = typeof data === 'object' && data instanceof Array && data.length > -1 ? data : [];
          
          console.log('ARRAY:: ', initArray);
          
          //Create and append url data list
          initArray.forEach(function(item) {
             console.log('item:: ', item);

            //Create a new <option> element.
            var option = document.createElement('option');
            console.log('option', option);
            
        		option.value = item;
            console.log('value', option);
            
        		// Add the <option> element to the <datalist>.
        		urlDataList.appendChild(option);
          });
          
          for(i = 0; i < initArray.length; i++) {
            console.log('obj');
            var option = document.createElement("option");
            option.value = initArray[i];
            
            urlDataList.appendChild(option);
  				}
				}          
        document.getElementById("urlBuilder").addEventListener("click", function(){
  				createUrlDropdown();
				});
      });
    </script>    
  </body>
</html>
  

感谢任何帮助!

【问题讨论】:

    标签: javascript html contentful


    【解决方案1】:

    ??

    问题出在getUrlData 函数中。 api.space.getEntries 返回一个您正确使用 then 的承诺。 Promise 的问题在于它们是异步的(就像 javascript 中的很多东西一样)。

    意味着您初始化urlDataArray 并调用内容。当电话回来时,你填充这个数组。问题是getUrlData 已经返回了一个空数组。

        function getUrlData(){
          var urlDataArray = [];
          api.space.getEntries()
          .then(function (entries) {
            // this part is executed async
            entries.items.forEach(function (entry) {
              if(entry.fields.url){
                var urlData = entry.fields.url.en
                urlDataArray.push(urlData);
              }
            })
        })
          return urlDataArray;
        };
    

    接近此 IMO 以更改 getUrlData 以也返回承诺的最佳方式。

    function getUrlData() {
      // return this promise
      return api.space.getEntries()
        .then(function(entries) {
          // there is no need for another array
          // you can use map to grab the data you need
          return entries.items.map(function(item) {
            // map all the entries to the url strings
            return item.fields.url.en;
          })
        })
    }
    
    getUrlData()
      // only execute this when the data is there
      .then(function(urls) { console.log(urls); })
    

    您的代码在 UI 扩展中运行,但我也很快在 codepen 中更改了您的代码。它使用 Contentful CDA,但原则保持不变。

    希望对您有所帮助。 :)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-27
      • 1970-01-01
      • 2013-04-19
      • 1970-01-01
      • 2015-12-21
      • 1970-01-01
      相关资源
      最近更新 更多