2013-08-19 3 views
2

У меня есть этот код http://jsfiddle.net/QRcF5/2/itemView вызвать пользовательское событие, достигающих parrent

$(function() { 
    var Header = Backbone.Marionette.ItemView.extend({ 
     template: _.template('<h4>TEST</h4><button>EDIT</button>'), 

     tagName: 'nav', 

     triggers: { 
      'click button': 'btn_clicked' 
     } 
    }), 
    Layout = Backbone.Marionette.Layout.extend({ 
     template: _.template('<header></header>'), 

     regions: { 
      header: 'header' 
     }, 

     events: { 
      'itemview:btn_clicked': 'clicked' 
     }, 

     clicked: function() { 
      alert('Ana are mere'); 
     } 
    }); 

    layout = new Layout(); 
    $('body').append(layout.render().el); 
    layout.header.show(new Header()); 
}); 

Я использую макет с одной ItemView (позже я хочу более сложную вложенности) и хотите, чтобы захватить в раскладке для события что происходит в ITEMVIEW. Кажется, что он не пузырится вверх, или я делаю что-то не так.


UPDATE 1 Я пробовал событие, триггера (для ребенка) и событие (для родителей), но я до сих пор не могу получить событие пойман внутри родителя.

можно использовать:

_.extend(App.vent, Backbone.Events); 

Backbone.Marionette.ItemView.extend({ 
    .... 
    App.vent.trigger('btn_clicked'); 
    .... 
}); 

Backbone.Marionette.Layout.extend({ 
    .... 
    App.vent.on('btn_clicked', function() { doCoding(); }); 
    .... 
}); 

Но этот путь я разорвать инкапсуляцию. Есть ли способ сохранить инкапсуляцию с помощью запуска триггеров Marionette и сохранить все это в макете и не загрязнять все приложение?


UPDATE 2

http://jsfiddle.net/QRcF5/5/

Я обновить jsfiddle использовать _.extend (вентиляционные, Backbone.Events). Если у кого-то есть лучший образец для этого, сообщите нам: D

ответ

8

Я нашел решение (похоронено где-то в документации делают некоторые связи между макетом, регион и вид)!

http://jsfiddle.net/QRcF5/6/


В контексте общения ТОЛЬКО между родителя (макет) и ребенок (itemView):

1) ребенок запускает пользовательский событие (в отличие от вентиляционного удлинения Backbone.Events - это только для тех, у кого есть доступ к нему = инкапсуляция)

triggers: { 
    'click button': 'custom_event:btn_clicked' 
} 


2) родитель слушать это событие , имеющего доступ к ребенку с на ('шоу', ....)

initialize: function() { 
    var that = this; // needed for the listenTo which overrides 'THIS' 

    this.header.on('show', function(view) { 
     this.listenTo(view, 'custom_event:btn_clicked', that.clicked); 
    }); 
}, 


Пример:

layout = new Layout(); 
$('body').append(layout.render().el); 
layout.header.show(new Header()); // Here we get access to child and its events 


(скрыто) мощность марионетки. (Я имею в виду, когда говорю скрытое, потому что, будучи относительно новым, документация является barebone и сложными примерами скудны).

С небольшим упорством все может быть достигнуто.

0
events: { 
      'itemview:btn': 'btn_clicked' 
     }, 

Элемент не на кличке. Необходимо указать фактический элемент DOM, как это:

events: { 
      'click .someThingWithAClass': 'myFunction' 
     }, 

Однако, если вы хотите слушать события, которые происходят дальше вниз по дорожке, вы, вероятно, следует просто придерживаться Jquery on метода. Это будет слушать все, что пузырь своего пути, независимо от того, пользовательского интерфейса, который был сформирован в то время, что эта точка зрения оказанной

http://api.jquery.com/on/

+0

Я использую itemview в пути: https://github.com/marionettejs/backbone.marionette/blob/master/docs/marionette.collectionview.md#itemremoved-event Возможно, я ошибаюсь. – Symba

+0

Что вы будете делать, это слушать события, которые происходят в объекте itemview, который существует в JS-коде. События, которые происходят в DOM, не совпадают с событиями, которые происходят в javascript. Если вы слушаете клики, которые происходят в DOM, тогда вы должны сделать это, используя нижний фрагмент кода, который я написал. Если вы слушаете события, которые происходят на объекте просмотра марионетки, тогда вы должны использовать свой путь (мой верхний) – Scott

+0

Я ищу связь между itemview и макетом в Marionette (например, у нас есть внутренняя связь между моделью и представлением в Backbone) – Symba

1

вы должны просто вернуться верно, и пусть щелчок пузырьком вверх в DOM см http://jsfiddle.net/aGaDY/:

var Header = Backbone.Marionette.ItemView.extend({ 
    template: _.template('<h4>TEST</h4><button>EDIT</button>'), 
    events: { 
    'click button': 'btn' 
    }, 
    btn: function() { 
    return true; 
    } 
}), 

Layout = Backbone.Marionette.Layout.extend({ 
    template: _.template('<div>Before:</div><header></header><div>After:</div><div class="body">Body Goes Here</div>'), 
    regions: { 
     header: 'header' 
    }, 
    events: { 
     'click': 'btn_clicked' 
    }, 
    btn_clicked: function() { 
     alert('Ana are mere'); 
    } 
}); 
layout = new Layout(); 
$('body').append(layout.render().el); 
layout.header.show(new Header()); 

Вы можете даже удалить обработку на ItemView укомплектовать событие, пузыриться поведение по умолчанию

EDIT:

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

Переместить данные о цели события с помощью функции данных Jquery и event.target:

// In Header 
bth:function(e){ 
    $(e.target).data("source", "myButton") 
} 
// .... 
// in the Layout 
btn_click: function(e){ 
    if ($(e.target).data("source") === "myButton") this.doSomething() 
} 

Другого варианта заключается в том, что макет будет проходить в заголовке локальных остов.Событие расширенного объекта, поэтому связь между ними будет конфиденциальной.

Я понимаю, вопрос о инкапсуляции, но я думаю, что читаемость будет лучше в глобальном App.Vent, что вы предложили

+0

@Symba You может помещать логин в функцию headt btn, важно только, чтобы вы вернули true, чтобы активировать барботирование. Я не понимаю, почему this.on ('click' ... требуется? Что не работает в jsfiddle? – ekeren

+0

извините, моя ошибка на этом последнем комментарии. – Symba

+0

Я сделал себя неправильно понятым. Я хочу вызвать пользовательский случай, потому что простой щелчок просто не работает (слишком общий, у меня есть много других кликов, кнопок и т. д.), и если я положу путь html (кнопка «click header»), то я создаю жесткую зависимость от структуры html (что крайне нежелательно). PS: в позвоночнике вам не нужно возвращать true, поскольку вы сказали, что «барботирование - это поведение по умолчанию» – Symba