{"action":"created","issue":{"url":"https://api.github.com/repos/AmpersandJS/ampersand-subcollection/issues/40","labels_url":"https://api.github.com/repos/AmpersandJS/ampersand-subcollection/issues/40/labels{/name}","comments_url":"https://api.github.com/repos/AmpersandJS/ampersand-subcollection/issues/40/comments","events_url":"https://api.github.com/repos/AmpersandJS/ampersand-subcollection/issues/40/events","html_url":"https://github.com/AmpersandJS/ampersand-subcollection/pull/40","id":55082385,"number":40,"title":"bubble change event if model was initially a member | closes #39","user":{"login":"aaronmccall","id":464531,"avatar_url":"https://avatars.githubusercontent.com/u/464531?v=3","gravatar_id":"","url":"https://api.github.com/users/aaronmccall","html_url":"https://github.com/aaronmccall","followers_url":"https://api.github.com/users/aaronmccall/followers","following_url":"https://api.github.com/users/aaronmccall/following{/other_user}","gists_url":"https://api.github.com/users/aaronmccall/gists{/gist_id}","starred_url":"https://api.github.com/users/aaronmccall/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aaronmccall/subscriptions","organizations_url":"https://api.github.com/users/aaronmccall/orgs","repos_url":"https://api.github.com/users/aaronmccall/repos","events_url":"https://api.github.com/users/aaronmccall/events{/privacy}","received_events_url":"https://api.github.com/users/aaronmccall/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/AmpersandJS/ampersand-subcollection/labels/bug","name":"bug","color":"e11d21"},{"url":"https://api.github.com/repos/AmpersandJS/ampersand-subcollection/labels/request","name":"request","color":"c7def8"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":4,"created_at":"2015-01-21T21:51:10Z","updated_at":"2015-01-22T20:59:47Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/AmpersandJS/ampersand-subcollection/pulls/40","html_url":"https://github.com/AmpersandJS/ampersand-subcollection/pull/40","diff_url":"https://github.com/AmpersandJS/ampersand-subcollection/pull/40.diff","patch_url":"https://github.com/AmpersandJS/ampersand-subcollection/pull/40.patch"},"body":""},"comment":{"url":"https://api.github.com/repos/AmpersandJS/ampersand-subcollection/issues/comments/71097525","html_url":"https://github.com/AmpersandJS/ampersand-subcollection/pull/40#issuecomment-71097525","issue_url":"https://api.github.com/repos/AmpersandJS/ampersand-subcollection/issues/40","id":71097525,"user":{"login":"aaronmccall","id":464531,"avatar_url":"https://avatars.githubusercontent.com/u/464531?v=3","gravatar_id":"","url":"https://api.github.com/users/aaronmccall","html_url":"https://github.com/aaronmccall","followers_url":"https://api.github.com/users/aaronmccall/followers","following_url":"https://api.github.com/users/aaronmccall/following{/other_user}","gists_url":"https://api.github.com/users/aaronmccall/gists{/gist_id}","starred_url":"https://api.github.com/users/aaronmccall/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aaronmccall/subscriptions","organizations_url":"https://api.github.com/users/aaronmccall/orgs","repos_url":"https://api.github.com/users/aaronmccall/repos","events_url":"https://api.github.com/users/aaronmccall/events{/privacy}","received_events_url":"https://api.github.com/users/aaronmccall/received_events","type":"User","site_admin":false},"created_at":"2015-01-22T20:59:47Z","updated_at":"2015-01-22T20:59:47Z","body":"Ah, I see now. Good question. I think we may want to handle `change:*` events separately from other events because they need more nuanced handling in terms of logic.\r\n\r\nI'd say that we don't bubble events that cause models to become members because they weren't a member until after the change event fired, whereas the reverse should bubble.\r\n\r\nMy thought process:\r\n\r\nSuppose I have an external event handler that is listening to events on one collection (A) and adding or removing them on another (B) based on some filters. When an event is received that makes a model from A eligible to be a member of B it is added, but the event only bubbles on A because B wasn't aware of it when the event occurred. On the other hand, if our external handler intercepts a change on a model that causes the model to be removed from B the event would still bubble on B because, at the time of the event, the model _was_ a member of B.\r\n\r\n```javascript\r\nfunction handler(A, B, filter) {\r\n  A.on('all', function (event, model) {\r\n    if (model.isState && model.collection === A) {\r\n      var isMember = B.get(model);\r\n      var passes = filter(model);\r\n      if (passes && !isMember) {\r\n        // B will never bubble change events that got us here\r\n        B.add(model);\r\n      } else if (!passes && isMember) {\r\n        // B will always bubble change events that got us here\r\n        B.remove(model);\r\n      }\r\n    }\r\n  });\r\n}\r\n```\r\n"}}