Привязка события backbone.js нарушает функциональность переключателей - PullRequest
3 голосов
/ 24 августа 2011

Я довольно новичок в Backbone.js, но я почти уверен, что все делаю правильно.

Вот мой вид Backbone и модели:

// ПОЛЬЗОВАТЕЛЬСКАЯ МОДЕЛЬ

var User = Backbone.Model.extend({
    defaults: {
        UserID: 0,
        FirstName: "",
        LastName: "",
        Assignment: 0,
        Selected: false
    },


    toggle: function (){
        var value = this.get("Selected");
        this.set({ Selected : !value });
    }

});

// ПОЛЬЗОВАТЕЛЬСКИЙ ВИД

var UserView = Backbone.View.extend({
    parentview: null, // the parent view

    initialize: function () {
        this.parentview = this.options.parentview
        this.template = $("#user-template")

        this.model.bind("change", this.render, this);
    },

    render: function () {
        var content = this.template.tmpl(this.model.toJSON());
        $(this.el).html(content);

        return this;
    },

    events: {
       "click ul li": "toggle"
    },

    toggle: function () {
        this.model.toggle();
    }

});

А вот шаблон JQuery, который я использую для представления каждого пользователя. Представление отображается внутри другого большого представления, то есть коллекции.

<ul  id="user-container"
    {{if Selected == 1 }} class="selected" {{/if}}
>
    <li class="col1" {{if Selected == 0}} style="visibility:hidden" {{/if}} >
        <img src="@Content.ImageUrl("pin-icon.png", "base")" />
    </li>
    <li class="col2">${FirstName} ${LastName} </li>
    <li class="col3-last">
        <input id="radio-${$item.view}-PM-${UserID}" name="radio-${$item.view}-${UserID}" type="radio" value="1" class="button"  
            {{if Assignment == 1}} checked="checked" {{/if}} 
        />
        <label for="radio-${$item.view}-PM-${UserID}">
            PM</label>
        <input id="radio-${$item.view}-SV-${UserID}" name="radio-${$item.view}-${UserID}" type="radio" value="2" class="button" 
            {{if Assignment == 2 }} checked="checked" {{/if}}
        />
        <label for="radio-${$item.view}-SV-${UserID}">
            STAFF</label>
        <input id="radio-${$item.view}-NA-${UserID}" name="radio-${$item.view}-${UserID}" type="radio" value="0" class="button" 
            {{if Assignment == 0 }} checked="checked" {{/if}}
        />
        <label for="radio-${$item.view}-NA-${UserID}">
            NONE</label>
    </li>
</ul>

В последнем li у меня есть три переключателя с динамическими идентификаторами и одинаковыми именами (также динамическими). Каждая кнопка имеет свою метку.

Все работало нормально, переключатели правильно выбирали и выполняли свою работу, пока я не добавил эту строку "click ul": "toggle" в событиях представления.

Событие срабатывает, когда я щелкаю по строке каждого пользователя в представлении, модель обновляется и пользователь выбирается / отменяется.

Единственное, что с этой строкой, радио кнопки просто не работают. Значения установлены, но ничего не происходит, когда я пытаюсь изменить значение (нажмите на другую кнопку-переключатель).

В консоли браузера не генерируется ошибка, что странно ...

ИСПРАВЛЕНИЕ: Когда я нажимаю переключатель, происходит событие щелчка в представлении магистрали, выбор выполняется, но кнопка не проверяется. Кажется, что магистраль вступает во владение, но все, что я хочу, это запускать, только когда я нажимаю на часть ul, а не на другие элементы внутри, такие как кнопки и т.д.

Однако, когда я нажимаю на ярлыки для кнопок, ничего не происходит. Событие магистрали не инициируется, и ни одна кнопка не выбрана.

Кто-нибудь знает, почему это может произойти?

1 Ответ

5 голосов
/ 04 сентября 2011

Флажок не изменен в пользовательском интерфейсе, потому что всякий раз, когда флажок нажимается, событие click распространяется на элемент "li" и вызывается обратный вызов переключения.Когда вызывается обратный вызов переключения, вы повторно визуализируете весь вид, и поскольку атрибут «Назначение» вашей модели пользователя не изменяется, вы повторно визуализируете представление с тем же «проверенным» состоянием, что иbefore.

Вы можете решить эту проблему, предотвратив распространение события click, когда оно инициализируется переключателем.Например, добавьте к вашему представлению следующий обработчик щелчков переключателя:

        events: {
            "click input[type=radio]": "onRadioClick",
            "click ul li": "toggle"
        },

        onRadioClick: function (e) {
            e.stopPropagation();
            this.model.set({ Assignment: $(e.currentTarget).val() }, {silent:true}); // {silent: true} is optional. I'm only doing this to prevent an unnecessary re-rendering of the view
        },

Это будет перехватывать событие щелчка при каждом нажатии переключателя и предотвращать вызов обратного вызова.Обратите внимание, что я также обновляю атрибут Assignment в вашей модели User, чтобы при повторном рендеринге вашего представления ваше проверенное состояние было правильно установлено.

...