简体   繁体   中英

When does a listView itemTemplate get inserted into the DOM?

I have created a custom itemTemplateFunction as described here . However I want to access attributes (such as height, or clientHeight) which are defined upon rendering in the DOM. This is to allow for a child element to be offset dynamically in the layout.

I've currently looked into two methods:

  • renderComplete - returned as an element in the itemPromise then return object. The event fired as expected, however the attributes (such as height) did not have set values, so it looks as though the item is not in the DOM at this point.
  • setInterval - although this would work it's a bad solution as I am relying on a constant time offset, something which ideally I don't want to do.

     function itemTemplateFunction(itemPromise) { return itemPromise.then(function (item) { var div = document.createElement("div"); var img = document.createElement("img"); img.src = item.data.picture; img.alt = item.data.title; div.appendChild(img); var childDiv = document.createElement("div"); var title = document.createElement("h4"); title.className += "title"; title.innerText = item.data.title; childDiv.appendChild(title); var desc = document.createElement("h6"); desc.innerText = item.data.text; childDiv.appendChild(desc); div.appendChild(childDiv); return { element: div, renderComplete: itemPromise.then(function (item){ return item.ready; }).then(function (item){ var height_a = div.querySelector(".title").clientHeight; var height_b = WinJS.Utilities.query(".title", div).clientHeight; }) } }); }; 

With the first item created the attributes still haven't been finalised, despite the promise being passed back. If however I wrap the return of item.ready in a second promise with a timeout interval of 0 this does return as expected.

       return {
           element: div,
           renderComplete: itemPromise.then(function (item){
               return WinJS.Promise.timeout(0).then(function () {
                   return item.ready;
               });
           }).then(function (item){
               var height_a = div.querySelector(".title").clientHeight;
               var height_b = WinJS.Utilities.query(".title", div).clientHeight;
           })
       }

The hook you're looking for is the item.ready property, once you're inside the completed handler for itemPromise.then().

item.ready is itself a promise that's fulfilled when the item gets rendered, at which point all the layout-dependent attributes should be set.

To use it, return item.ready from your first completed handler for itemPromise.then, and then add another .then(function (item) {} ) to the chain. Inside that complete handler is where you can check the attributes.

I go into some detail on this in Chapter 7 of my free ebook, Programming Windows Store Apps in HTML, CSS, and JavaScript, 2nd Edition , specifically in the section at the end of the chapter called "Template Functions (Part 2): Optimized Item Rendering" and the discussion of multistage rendering. The same content also appeared on the older Windows 8 developer blog , although note that the "recycling placeholder" option discussed on the blog is for WinJS 1.0 only.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM