-1

Is there a way to detect list change in canjs and make the view redraw? I am changing the list but this is not shown on screen.
At the moment i have view model

TodosListViewModel = can.Map.extend({
todoCreated: function(context, element) {
  // new todo is created
  var Todo = this.Todo;
  new Todo({
    name: can.trim(element.val())
  }).save();
  element.val("");      
},
tagFiltered: function(context, element) {
  // filter todos according to tag
  this.todos = this.todos.filter(function(todo) {
    return todo.tag === element.val();
  });
}

});
And component

can.Component.extend({
// todos-list component
// lists todos
tag: "todos-list",
template: can.view("javascript_view/todos-list"),
scope: function() {
  // make the scope for this component
  return new TodosListViewModel({
    todos: new TodoList({}),
    Todo: Todo
  });
},
events: {
  "{scope.Todo} created": function(Todo, event, newTodo) {
    // todo created
    this.scope.attr("todos").push(newTodo);
  },
  "{scope.todos} changed": function(a,b,c,d,e,f,g,h) {
    console.log("todo change",d,e);
  }
}

});
The markup

<input type="text" name="tagFilter" placeholder="Tag lookup" can-enter="tagFiltered" />  

The rest of code http://git.io/vrPCTQ

4

1 回答 1

0

In the case you're showing in the fiddle, you haven't define "page" in the scope to take a raw string value from the component's tag (using "@" as the value for scope.page). Check out the one-line difference in router's scope here:

http://jsfiddle.net/tkd9Lvtm/3/

EDIT: That didn't address the original question, so here's what else you can do to get this started. I made a new fiddle version for you.

http://jsfiddle.net/tkd9Lvtm/4/

The best way with CanJS 2.1 to accomplish what you want is to use can-value attributes on your form fields to two-way bind your elements to attribute values on your view model. You can see that the input field for the tag search is now using can-value instead of can-change -- this makes it independent of the filter function, which is only used to draw the items farther down.

CanJS will automatically rerun the filter when the attribute changes, because calling this.attr("filterTerm") inside the view model's filter function sets up binding the first time it's run. The live bound view layer is making computes out of these functions "under the hood" and these computes (a) listen to changes on attributes that are read inside the function; and (b) updates the DOM with each change to listened-to attributes. Using the view model to store the value in the filter field then allows that function to fire again on each change.

于 2014-10-08T18:45:33.367 回答