在HTML端从Javascript呈现项目时传递正确的信息

问题描述 投票:0回答:1

我正在尝试使用他们的扩展工具包(https://docs.microsoft.com/en-us/vsts/extend/overview?view=vsts)为VSTS创建扩展。

 <script type="text/javascript">

        VSS.init();

        var items = {}

        // Get data service and display

        VSS.getService(VSS.ServiceIds.ExtensionData).then((dataService) => {
            dataService.getDocuments('MyCollection2').then((docs) => {
                // keep a reference to the element instead of searching for it in each loop.
                const itemsDiv = document.getElementById('items');
                const contents = [];

                for (let i = 0; i < docs.length; i++) {
                // using template strings here to show you another way of working with strings in es6

                    var name = docs[i].name

                    contents.push(
                        `<div 
                            class="listItem"
                            onClick="console.log(docs[i])"
                            onmouseover="this.style.background='#D5DBDB';" 
                            onmouseout="this.style.background='white';">
                            ${docs[i].name}
                        </div>`
                    )
                }

                // finally update the target element one time with your contents. 
                // The new line character isn't required, can just use '', 
                // but this might be easier to read for you

                itemsDiv.innerHTML = contents.join('');
            });
        });
</script>

所以我的javascript部分是我尝试从VSTS的内部数据存储中获取对象(我将其命名为MyCollection2)并将对象显示为列表

HTML部分

    <section>
            <nav>
              <div class="create_button">+ Create KPI</div>
              <div id="items"></div>
            </nav>

            <article>
                <h2>Create KPI</h2>
                <br>
                <form action="" id="form" onsubmit="sConsole(event)">
                    KPI Name<br>
                    <input type="data" id="name">
                    <br><br>
                    Actual Value<br>
                    <input type="data" id="actual">
                    <br><br>
                    Potential Value<br>
                    <input type="data" id="potential">
                    <br><br>
                    Goal %<br>
                    <input type="data" id="goal">
                    <br><br>
                    <button type="submit">Create</button><span>Cancel</span>
                </form> 
            </article>
          </section>

所以所有的对象都在id中用items渲染。

到目前为止,一切都很好。

问题是我的javascript部分中的onClick="console.log(docs[i])部分。

我的意图是每当单击列表中的每个项目时,都会调度文档对象。

但是,这不会像我预期的那样打印对象。

它只是打印externalContentHost10,我不知道那是什么。

我能做些什么来完成这项工作?

javascript html azure-devops
1个回答
1
投票

docs在你的函数中定义; onclick属性的范围(注意:应全是小写)是不一样的。一般来说,你应该avoid inline event handlers,因为他们不是非常灵活或可维护。你应该使用addEventListener,这意味着放弃innerHTML并使用适当的元素节点。我要做的其他一些改变是:

  • 通过返回承诺来展平承诺(删除嵌套)
  • 使用for...of进行迭代
  • 使用const(和let,但在这种情况下const就足够了)而不是var,这样你的变量就有了正确的范围

这给了我们:

VSS.init();

const items = {};

// Get data service and display

VSS.getService(VSS.ServiceIds.ExtensionData)
   // the callback on the next line returns a promise, which the JavaScript engine will follow, so you don't need to nest the next `then`
  .then((dataService) => dataService.getDocuments('MyCollection2'))
  .then((docs) => {
    // keep a reference to the element instead of searching for it in each loop.
    const container = document.getElementById('items');

    // this loop will remove any existing children
    while (container.firstChild !== null) {
      container.removeChild(container.firstChild);
    }

    // `for...of` is a simpler way to iterate over a collection
    for (const doc of docs) {
      // create a `div` element
      const div = document.createElement("div");

      // add a text node to it
      div.appendChild(document.createTextNode(doc.name));

      // add event listeners to change its background
      div.addEventListener("mouseover", e => { div.style.background = "#D5DBDB"; });
      div.addEventListener("mouseout", e => { div.style.background = "white"; });

      // add a `click` listener
      div.addEventListener("click", e => { console.log(doc); });

      // add the new div to the container
      container.appendChild(div);
    }
  });

如果你想使用类来管理样式 - 这是推荐的方法 - 那么你可以使用classList实现事件监听器:

div.addEventListener("mouseover", e => div.classList.add("hover-class"));
div.addEventListener("mouseout", e => div.classList.remove("hover-class"));

classListtogglereplace方法,但它们根本不受IE支持,而Edge似乎只支持toggle,因此是否使用它们取决于您支持的最低版本。)

但是你可能最好定义一个CSS :hover类,而不是做所有这些,如果样式是你想要改变的。

© www.soinside.com 2019 - 2024. All rights reserved.