Hi I need an advise about how to organize general approach for components that I use in an application.
I have some pre-conditions that I should mention:
-
Right now the application is old-fashioned multi-page Java application that uses
JSP
. What we are doing right now is migrating some pieces that we can tocanjs
. It means that components that I create should have an ability to be used incanjs
pages (stache
) and in just plainHTML
pages with plainJS
(orjQuery
). -
I’m using
canjs
2.2.9
I know that its pretty old, but unfortunately this is something that I can’t change in the nearest future.
I created small component (still WIP, but can represent my question):
https://dl.dropboxusercontent.com/u/25491580/can-test/index.html
(Sorry it’s not JSBin
because there are different files, folders so it was easier to share in that way, but I can probably post it on Github
if its easier than checking sources in devtools)
Basically this is textarea that should count amount of characters, change height and react when character limit exceeds (twitter / facebook like).
I would like to find a way how to react on event that I dispatch here:
isLimitExceeded: {
type: 'boolean',
set: function (newValue) {
if (this.isLimitExceeded !== newValue) {
can.event.dispatch.call(this, 'super-input:limitStatusChange');
}
return newValue;
}
},
(actually I can implement something different, but event looks straightforward way for organizing communication to me)
The only way that I found is to do something like this:
can.event.on.call(can.viewModel(element.find('super-input')), 'super-input:limitStatusChange', function() {
// do some logic
});
For parent component I have to do this in parent component inserted
event in order to ensure that we have super-input inside:
can.Component.extend({
tag: 'comment-adder',
template: can.view('/t_static/can-components/comments/comment/comment-adder/comment-adder.template.stache'),
viewModel: commentAdderViewModel,
leakScope: false,
events: {
inserted: function (element) {
can.event.on.call(can.viewModel(element.find('super-input')), 'super-input:limitStatusChange', function () {
// do some logic
});
}
}
});
And outside…well I guess I just need to ensure that this DOM
element exist and do something similar.
This approach looks suspicious to me Is it correct to do something like that ?
I know that there is better viewBindings
available in canjs > 2.3.x
but it won’t help if I would like to listen to this event from some other part of page that isn’t can.js
component.
Besides if I need to set / get component data from JS
that isn’t part of can application I also use similar approach:
can.viewModel($('super-input')).attr('message', 'new message');
Is it ok to do this, because this construciton can.viewModel(element)
seems like I use something internal, I shouldn’t build my solution on top of such calls ?