My rule of thumb for putting code as overrides in a view is whether or not the code requires knowledge of the component's DOM elements so that controllers can stay focused on application logic and designers can tweak DOM manipulations, for example if the view used a custom template. I try to limit the view functions to overrides of template methods and the automagic config accessors (usually update*). If you need your controller to listen to events from any custom elements in your view, override the initEvents template method (be sure to callParent) to hook up mini listeners that translate page events to application events, e.g.:

Code:
config: {
	users: null
}
,tpl: '<tpl for="users"><a href="#{username}" class="user">{fullname}</a></tpl>'

,initEvents: function() {
	var me = this;
	me.callParent();
	
	// use delegate event on persistent common element instead of attaching to individual identical or transient elements
	me.el.on('click', function(ev, t) {
		ev.stopEvent();
		me.fireEvent('userClick', me, t.hash.substr(1), ev, t); // first param should always be the thing firing the event, then any meaningful information you can extract from ev or t, and finally all the original DOM event parameters
	}, me, {delegate: 'a.user'});
}

// override the autocreated empty updateUsers method, it gets called when your controller calls setUsers or passes in a users config when creating the component
,updateUsers: function(users) {
	this.update({users: users});
}