2

I would like to add an event listener in in <some-component> that reacts to the button.

<some-component></some-component>
<button class="click">click here</button>

I am sure this is really simple. I am very new to CanJS and working on it.

<can-component tag="some-component">
<style type="less">
    <!-- stuff -->
</style>
<template>
    <!-- stuff -->
</template>
<script type="view-model">
import $ from 'jquery';
import Map from 'can/map/';
import 'can/map/define/';

export default Map.extend({
  define: {
    message: {
      value: 'This is the side-panels component'
    }
  }
});
</script>
</can-component>

I tried adding a $('body').on('click', '.click', function() {}); to the component and it didn't seem to work. Been reading a lot of documentation, but I am still missing some fundamental understanding.

UPDATE

I tried this:

<some-component-main>
    <some-component></some-component>
    <button class="click">click here</button>
</some-component-main>

with the event listener in some-component-main

events: {
  ".click click": function(){
    console.log("here I am");
  }
},

But that also didn't work.

2 Answers2

1
<some-component-main>
    <some-component></some-component>
    <button class="click">click here</button>
</some-component-main>

with the event listener in some-component-main

events: {
  ".click click": function(){
    console.log("here I am");
  }
},

This did work once I realized that components ending with a number causes other issues that was preventing it.

1

You can make things inside your component available to the parent scope using the {^property-name} or {^@method-name} syntax. Read about it here: https://canjs.com/docs/can.view.bindings.toParent.html

Here's a fiddle: http://jsbin.com/badukipogu/1/edit?html,js,output

In the following example, <my-compontent> implements a doSomething method and we the button to call that method when clicked. We expose the method as "doFooBar".

<my-component {^@do-something}="doFooBar" />
<button ($click)="doFooBar">Button</button>

and the code:

can.Component.extend({
  tag: "my-component",
  template: can.view('my-component-template'),
  viewModel: can.Map.extend({
    doSomething: function () {
      alert('We did something');
    }
  })
});

But why does the example use ^@do-something="..." instead of ^@doSomething="..."??

DOM node attributes are case insensitive, so there's no way to tell the difference between doSomething="", DoSomEthiNg="", or DOSOMETHING="" - all three are equivalent. CanJS is following the way browsers work by converting attributes with dashes to camelCase and vice versa.

Consider native data attributes - if you do something like <div data-my-foo="my bar">, then the value is accessible via JavaScript by doing [div].dataset.myFoo (notice the camelCasing). The same applies to css properties where css uses "background-color" but javascript uses backgroundColor. CanJS is following this convention.

Ryan Wheale
  • 26,022
  • 8
  • 76
  • 96