cloudcrypt
cloudcrypt

Reputation: 809

Event Handler Binding of WinJS.UI.Repeater item to Object method

I'm currently trying to bind the onchange event of a <select> to an event handler inside that is an object method (JavaScript class written in TypeScript) as so:

HTML:

<div id="readerTemplate" data-win-control="WinJS.Binding.Template">
  <div>
    <select class="win-dropdown" 
            data-win-control="WinJS.UI.Repeater" 
            data-win-options="{data: versions}" 
            data-win-bind="value: version; onchange: versionChangeHandler">
      <option data-win-bind="value: fileName; textContent: versionName">
      </option>
    </select>
    <div class="win-type-title" data-win-bind="textContent: version"></div>
  </div>
</div>

JS/TypeScript:

loadTabsUI(pivot: WinJS.UI.Pivot) {
  for (let tab of this.tabs) {
    var tabDiv = document.createElement("div");
    var pivotItemDiv = document.createElement("div");
    var pivotItem = new WinJS.UI.PivotItem(pivotItemDiv);
    pivotItemDiv.setAttribute('data-win-bind', 'winControl.header: title');
    var rptrDiv = document.createElement("div");
    var rptr = new WinJS.UI.Repeater(rptrDiv, { "data": tab.readers, "template": document.getElementById("readerTemplate").winControl });
    pivotItem.contentElement.appendChild(rptrDiv);

    pivot.items.push(pivotItem);

    WinJS.Binding.processAll(pivotItemDiv, tab);
  }
}

Line where binding is taking place:
var rptr = new WinJS.UI.Repeater(rptrDiv, { "data": tab.readers, "template": document.getElementById("readerTemplate").winControl });

Reader class with method:

class Reader {
  ...
  ...
  versionChangeHandler(evt: UIEvent): void {
    // goal is to execute the following line:
    this.setVersionAsync((evt.target as any).value);
  }
  ...
  ...
}

When the selection of the <select> is changed, the versionChangeHandler does get called. However, the issue is that I'm not able to access the correct this inside the function, which prevents me from running setVersionAsync on the right object instance, which is the object instance that was used by the WinJS.UI.Repeater (in the binding from the JS earlier) to populate/bind the readerTemplate.

Any ideas on solving this issue? (I am calling this WinJS.Utilities.markSupportedForProcessing(this.versionChangeHandler); in the constructor of the Reader class, since otherwise I hit an exception with the binding.)

Thanks!

Upvotes: 0

Views: 202

Answers (1)

Elvis Xia - MSFT
Elvis Xia - MSFT

Reputation: 10831

However, the issue is that I'm not able to access the correct this inside the function.

It is because the context has changed. You can use the following codes to fix this issue:

class Reader {
   public handlerProxy: any;

   constructor() {
     this.handlerProxy = (evt: UIEvent) => { this.versionChangeHandler(evt, this); }
   }
   ...
   ...
   versionChangeHandler(evt: UIEvent,that): void {
     // goal is to execute the following line:
     that.setVersionAsync((evt.target as any).value);
   }
  ...
  ...
}

And in your HTML change versionChangeHandler to handlerProxy:

<div id="readerTemplate" data-win-control="WinJS.Binding.Template">
<div>
<select class="win-dropdown" 
        data-win-control="WinJS.UI.Repeater" 
        data-win-options="{data: versions}" 
        <!--here change versionChangeHandler to handlerProxy.-->
        data-win-bind="value: version; onchange: handlerProxy">
  <option data-win-bind="value: fileName; textContent: versionName">
  </option>
</select>
<div class="win-type-title" data-win-bind="textContent: version"></div>

Upvotes: 1

Related Questions