سؤال

I can create repeater by this way:

    <div class="gameField" id="gameField" data-win-control="WinJS.UI.Repeater" data-win-options="{ data: GameField.cells}">
        <div class="gameCell">
            <img data-win-bind="src: symbol GameField.cellSymbolToImg" width="100" height="100" />
        </div>
    </div>

and js

    var Cell = WinJS.Class.define(function(number) {
    this.number = number;
    this.symbol = "";
});

var getCellsList = function () {
    var cells = [];
    for (var i = 1; i < 10; i++) {
        var cell = new Cell(i);

        cells.push(cell);
    }
    return cells;
};

var cellsList = new WinJS.Binding.List(getCellsList());
WinJS.Namespace.define("GameField", {
    cells: cellsList,
    cellSymbolToImg: WinJS.Binding.converter(function (symbol) {
        return symbol == "" ? "" : "symbol_" + symbol + ".png";
    })
});

But how can I bind click event to some function so that I could access underlying cell object from within that function?

هل كانت مفيدة؟

المحلول

This is straightforward to do using the function.bind method, and you can even have the handler directly in your Cell class.

var Cell = WinJS.Class.define(function(number) {
    var e = document.createElement("div"); //...and initialize however.
    this.element = e;
    e.winControl = this;

    this.number = number;
    this.symbol = "";
    //Also consider using pointerDown event here instead of click; might respond quicker
    e.addEventListener("click", this._click.bind(this));
}, {
    //Instance members
    _click: function (e) {
        //Your handler. "this" will be the instance of Cell that was clicked
    }
});

The this._click function, as you can see, refers to the instance member Cell._click. Calling this function's bind method is how you then specify the exact object to use as "this" inside that method. Without the call to .bind(this), the handler would still be invoked but "this" would be the global context and not the object you care about.

نصائح أخرى

Sorry, I never got your solution running, but i I found another way to bind the click in a repeater. I will just post my sample for a Navigation

<ul data-win-control="WinJS.UI.Repeater" data-win-bind="winControl.data: navigations">
    <li data-win-control="Navigation.NavigationItem" data-win-bind="winControl.data: this">
        <span data-win-bind="textContent: Name; className: Selected;"></span>
        <span data-win-bind="textContent: Selected;"></span>
    </li>
</ul>

As you can see i created a very simple control and bound the repeater item with "data-win-bind="winControl.data: this".

The namespace looks like this:

WinJS.Namespace.define("Navigation", {
    dataBinding: WinJS.Binding.as({
        navigations: new WinJS.Binding.List([]),
    }),

    NavigationItem: WinJS.Class.define(
            function (element, options) {
                this.element = element;
                this.element.onclick = function (event) {                        
                    var item = this.winControl.data;
                    // Handle your onclick here
                    // for example: 
                    item.clickHandler();
                };
            }
        ),
});

And items are added like this:

Navigation.dataBinding.navigations.push(WinJS.Binding.as({
    Name: "Home",
    Page: "/pages/home/home.html",
    // more... for example:
    clickHandler: function() {
       // Do Something
    };
}));
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top