Closed aristov closed 9 years ago
what logic is duplicated? An example?
Any behaviour, that I can implement as button
's modifier. When designer draws a pseudo link, which behaviour can be implemented in the same way, I have to duplicate this logic by using link_pseudo
. But I wanna use button
with already implemented behaviour and just say, that it should be represented as pseudo link by adding _view_link
.
For example: not long ago I've noticed, that it's very convenient to learn button
to send AJAX requests on click
by itself. Simplified code example:
Button.decl({ modName : 'action', modVal : 'request' }, {
onSetMod : {
'js' : {
'inited' : function() {
this.__base.apply(this, arguments);
var _this = this;
this.on('click', function() {
$.ajax(this.params)
.success(function(result) {
_this.emit('success', result);
})
.error(function(error) {
_this.emit('error', error);
});
});
}
}
}
});
Now I can do any request by tuning button_action_request
with it's js-params and don't need to write any client-side code, only external block's reaction on success
/error
events of button
. If I have a pseudo link, that should send AJAX request, I have to duplicate this logic by create link_action_request
and use it with link_pseudo
.
I don't wanna to create a third entity, that will implement AJAX request and share it's logic with button
and link_pseudo
. In my opinion this is redundant entity multiplying. If button
can do it by itself, so why should I create something else?
I can imagine more number of useful modifiers for button
, example above is just one of them.
What about another entity? Ex: request-trigger
.
{ block: 'button', mix: { block: `request-trigger`, js: { event: 'click', request: {} } } },
{ block: 'link', mix: { block: `request-trigger`, js: { event: 'hover', request: {} } } },
{ block: 'input', mix: { block: `request-trigger`, js: { event: 'change', request: {} } } }
BEMDOM.decl({ block: 'request-trigger' }, {
onSetMod : {
'js' : {
'inited' : function() {
var _this = this;
this.on(js.params.event, function() {
$.ajax(this.params.request)
.success(function(result) {
_this.emit('success', result);
})
.error(function(error) {
_this.emit('error', error);
});
});
}
}
}
});
@awinogradov :fire: :fire_engine:
What about another entity? Ex: request-trigger.
This won't work, because bem-event fires on the instance, not DOM-node of the block. You can not write this.on(event, fn() {})
to subscribe the event of the mixed block. You can parametrize target by js-params and do something like this.findBlockOn(params.target).on(event, fn() {})
. But this approach breaks lazy initialization of the target block. Moreover, your request-trigger
can not work as lazy block. If you try to make it lazy by using this.liveInitOnBlockEvent
in live
section, you find out that you can't parametrize target.
You can put target block into custom request-trigger
param and take block name in the template.
{
block: 'request-trigger',
target: {
block: 'link'
}
}
this.ctx.js.target = this.ctx.taget.block
js-params are available only for instance of the block. You can not get them from the live
section.
Logic duplication example from the codebase:
Discussed and rejected by the core maintainers team.
Link is just link, it shouldn't have button's semantics. We should create semantics from component's behaviour, but not the view. This change can help to reduce logic duplication in the projects codebase. Also this approach more clear form the
a11y
POV.This change breaks backward compatibility.