{"action":"created","issue":{"url":"https://api.github.com/repos/ckeditor/ckeditor5-ui/issues/90","repository_url":"https://api.github.com/repos/ckeditor/ckeditor5-ui","labels_url":"https://api.github.com/repos/ckeditor/ckeditor5-ui/issues/90/labels{/name}","comments_url":"https://api.github.com/repos/ckeditor/ckeditor5-ui/issues/90/comments","events_url":"https://api.github.com/repos/ckeditor/ckeditor5-ui/issues/90/events","html_url":"https://github.com/ckeditor/ckeditor5-ui/issues/90","id":183997437,"number":90,"title":"Feature as controller","user":{"login":"pjasiun","id":1166967,"avatar_url":"https://avatars.githubusercontent.com/u/1166967?v=3","gravatar_id":"","url":"https://api.github.com/users/pjasiun","html_url":"https://github.com/pjasiun","followers_url":"https://api.github.com/users/pjasiun/followers","following_url":"https://api.github.com/users/pjasiun/following{/other_user}","gists_url":"https://api.github.com/users/pjasiun/gists{/gist_id}","starred_url":"https://api.github.com/users/pjasiun/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pjasiun/subscriptions","organizations_url":"https://api.github.com/users/pjasiun/orgs","repos_url":"https://api.github.com/users/pjasiun/repos","events_url":"https://api.github.com/users/pjasiun/events{/privacy}","received_events_url":"https://api.github.com/users/pjasiun/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":1,"created_at":"2016-10-19T15:35:48Z","updated_at":"2016-10-19T16:00:19Z","closed_at":null,"body":"**tl;dr: UI MVC is overcomplicated. It should be possible to create the whole code of the controller inside the feature.**\r\n\r\nHere is my use case:\r\n\r\nI was writing a feature which takes a collection of users and displays the content of it (assume that I already have a `User` and `Users` model classes). I did not want to make it reusable.\r\n\r\nI created `UsersFeature`, `UsersView`, `UserView`, `UsersController` and  `UsersController` and had a feeling that it's overengineered. Also, all my controllers do is:\r\n\r\n```js\r\nexport default class User extends Controller {\r\n\tconstructor( model, view ) {\r\n\t\tsuper( model, view );\r\n\r\n\t\tview.bind( 'name' ).to( model );\r\n\t}\r\n}\r\n```\r\nAnd:\r\n\r\n```js\r\nexport default class Users extends Controller {\r\n\tconstructor( model, view ) {\r\n\t\tsuper( model, view );\r\n\r\n\t\tthis.addCollection( 'users' );\r\n\t}\r\n}\r\n```\r\n\r\nAlso, I realized that there are many such controllers in the code (both in my project and in the UI default lib).\r\n\r\nI understand that in the UI default lib which contains reusable component it makes sense to create such structures, but in my case it was useless.\r\n\r\nMoreover, I understand the controller as a piece of the code which binds model and view, handles the initialization and the data transformation between the model and the view.\r\nAccording to this definition, It is not a real controller, because the whole code which was handling initialization and binding model with the view was in the feature.\r\n\r\nThen, @Reinmar told me that I can avoid creating these classes controller by creating `Controller` class and do it this way:\r\n\r\n```js\r\nconst usersCotroller = new Controller( usersModel, usersView );\r\nusersCotroller.addCollection( 'users' );\r\n\r\nusersCotroller.collections.get( 'users' ).bind( usersModel ).as( ( userModel ) => {\r\n\tconst userView = new UserView( locale );\r\n\tuserView.bind( 'name' ).to( user );\r\n\treturn new Controller( userModel, userView );\r\n} );\r\n```\r\n\r\nStill, I see 2 problems here:\r\n - I need to create instances of `Controller` without the clear understanding what it does,\r\n - I need to add a collection to the first controller (`usersModel` has a collection of `userModel`s and `usersView` has a collection of `userView`s, why I need add to the `usersController` collection of `userController`s?).\r\n\r\nI would like to write in the `UsersFeature`, which is a real controller, code which binds model and view without a need of creating additional `Controller`s. `bind` could be a method of the collection and I should be able to do:\r\n\r\n```js\r\nusersView.users.bind( usersModel ).as( ( userModel ) => {\r\n\tconst userView = new UserView( locale );\r\n\tuserView.bind( 'name' ).to( user );\r\n\treturn userView;\r\n} );\r\n```\r\n\r\nAs I learned the idea behind controllers was that they will handle destruction chain and prevent memory leaks. The problem is, that in this case, they are the reason for the memory leak. Before writing this post I did not realize that I have to store `usersCotroller` as a private property and call `usersCotroller.destroy()` in the feature `destroy()` function."},"comment":{"url":"https://api.github.com/repos/ckeditor/ckeditor5-ui/issues/comments/254858278","html_url":"https://github.com/ckeditor/ckeditor5-ui/issues/90#issuecomment-254858278","issue_url":"https://api.github.com/repos/ckeditor/ckeditor5-ui/issues/90","id":254858278,"user":{"login":"pjasiun","id":1166967,"avatar_url":"https://avatars.githubusercontent.com/u/1166967?v=3","gravatar_id":"","url":"https://api.github.com/users/pjasiun","html_url":"https://github.com/pjasiun","followers_url":"https://api.github.com/users/pjasiun/followers","following_url":"https://api.github.com/users/pjasiun/following{/other_user}","gists_url":"https://api.github.com/users/pjasiun/gists{/gist_id}","starred_url":"https://api.github.com/users/pjasiun/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pjasiun/subscriptions","organizations_url":"https://api.github.com/users/pjasiun/orgs","repos_url":"https://api.github.com/users/pjasiun/repos","events_url":"https://api.github.com/users/pjasiun/events{/privacy}","received_events_url":"https://api.github.com/users/pjasiun/received_events","type":"User","site_admin":false},"created_at":"2016-10-19T16:00:18Z","updated_at":"2016-10-19T16:00:18Z","body":"In fact, thinking about it in the more generic way, my point is that `Controller` should be **a** `Controller` which helps you creating a controller, not **the** only `Controller` you need to use to bind view and model. Part of its functionality should be moved as tools which you can use separately. The same way that there is a `Model` class you can use as a base of your class, but any class which mix `Obseravbles` or even fire proper events can be a model."}}
{"actor":{"display_login":"pjasiun"}}