Вопрос

Ok, I just stepped into something tricky. I need to fire an event on my app everytime a major update happens (because I want multiple windows opened, therefore they need to be updated). The thing is, with that event, I wish to pass an argument, something like this:

Ti.App.fireEvent('updateViews', {data: my_data});

So far so good, but when I receive this event I want to be able to access its data. The only way I found out to do so is to create an anonymous function, like this:

Ti.App.addEventListener('updateViews', function(data) 
{ 
     var name = data.name; 
});

Great! That works! Now the big problem.. when I close this window, I need to remove that listener... Otherwise I'll end up with a memory leak. The thing is, if I change the anonymous function and pass it to a handler, I'm unable to access the data - but if I don't, I cant reference the function to successfully remove it. Please, help!

PS: There IS a way to do this, of course I could pass the data using Alloy.Globals (or the equivalent in the standard Ti), but I want a CLEAN, elegant solution that does not involve using Alloy.Globals. Thanks in advance.

Это было полезно?

Решение 2

So.. I figured it out. You can actually do that.. The problem was that I was registering the handler the wrong way. It will work if you just only set the handler to receive data. Example for the above code:

var handler = function(data) {
  var name = data.name;
  alert(name);
}
Ti.App.addEventListener('updateViews', handler);

Then, to remove it:

Ti.App.removeEventListener('updateViews', handler);

Другие советы

Is there a reason you need to use global app events? They make code more difficult to maintain and result in tighter coupled dependencies that are brittle when something changes. It also increases side effects when attempting to understand the code (Your future self will forget and you will get lost and confused).

The problem your experiencing is probably from the assumption that by assigning to a data property that it becomes the argument. The object you pass into fireEvent will be the object passed to the callback argument.

Ti.App.fireEvent('updateView', {data: {name: "foo"}});
Ti.App.addEventListener('updateView', function(e) {
  var name = e.data.name;
});

That being said, events in general can easily pass data via the fireEvent as you demonstrated. I find in cases of 'click' events I'm more interested in static data then in dynamic data. I use partial applications for this: (example uses underscore provided by Alloy, but the functionality can easily be polyfilled)

var _ = Alloy._;
var titles   = ['foo', 'bar', 'baz'];
var messages = [
  'This ia s foo message.',
  'But a bar message is better.',
  'Then again a baz message trumps them all.'
];

function onClick(message, e) {
  e.cancelBubble = true; // Not required but shows how to access the event object
  alert(message);
}

var tableData = _(titles).map(function(title, index) {
  var row = Ti.UI.createTableViewRow({title: title});
  row.addEventListener('click', _.partial(onClick, messages[index]));
  return row;
});

var table = Ti.UI.createTableView({
  data: tableData
});
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top