0

I am trying to detect created event in component. Nothing happens.

can.Component.extend({
// todos-list component
// lists todos
tag: "todos-list",
template: can.view("javascript_view/todos-list"),
scope: {
  Todo: Todo,
  todos: TodoList.slice(0),
  todoCreated: function(context, element) {
    // new todo is created
    var Todo = this.Todo;
    new Todo({
      name: can.trim(element.val())
    }).save();
    element.val("");
  }
},
events: {
  "{Todo} created": function(Todo, event, newTodo) {
    console.log("created");
  }
}
});

The model is

var Todo = can.Model.extend({
// todo model
// fetches things and so on
findAll: function() {
  // get all todos
  return $.Deferred().resolve(todos);
},
findOne: function(params) {
  // get one todo
  return $.Deferred().resolve(todos[(+params.id) - 1]);
},
create: function(attributes) {
  // creates new todo
  var last = todos[todos.length - 1];
  $.extend(attributes, {id: last.id + 1, detail: "", tag: ""});
  todos.push(attributes);
  return $.Deferred().resolve(attributes);
},
update: function(id, attributes) {
  // update one todo
  $.extend(todos[id - 1], attributes);
  return $.Deferred().resolve();
},
destroy: function() {
  // destroy todo
  return $.Deferred().resolve();
}
}, {});

Markup is

<input type="text" name="todo" placeholder="What needs to be done" can-enter="todoCreated" />  

Is this correct way of handling created event or is there a better way?
I need list to react when new todo is created.
See here for code

Kara
  • 6,115
  • 16
  • 50
  • 57
php--
  • 2,647
  • 4
  • 16
  • 18

1 Answers1

0

This is a bug: https://github.com/bitovi/canjs/issues/1261

This is due to CanJS treating the Todo constructor as a method because Todo is a JS function.

You can get around this by setting Todo on the can.Map instance used as the scope directly as shown here:

http://jsfiddle.net/c3bfy/147/

The trick is to create a separate view model with the methods you want on the scope:

TodoListViewModel = can.Map.extend({
  todoCreated: function(context, element) { ... }
});

And to change your scope to return an instance of this view model with Todo as a property:

scope: function(){
    return new TodoListViewModel({Todo: Todo})
},

This forces Todo to be treated as a property and not a method.

Justin Meyer
  • 1,677
  • 13
  • 15