-
Notifications
You must be signed in to change notification settings - Fork 20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Simplify API for child views #238
Comments
@pepperbc can you please give an example of a complex view with the current API and how it would change with this API. I would like to see a side-by-side comparison of the APIs so that I can better see what this is trying to address. |
|
Basically it removes the need for redundant injections in "attachTrackedViews", and redundant render listeners when you hide/show/first inject a child view. The additional show/hide functionality could potentially remove some boilerplate functions depending on the use case. I'm sure there are some edge cases I'm forgetting about - any ideas what they are? |
This makes a few assumptions. Just pointing them out so we know what comes with this. First, that you use the same injection site name always (even so far as changing the template you are using if someone overrides the updateDOM method). Second, the check to find out if you should inject/not inject a view is able to be stored prior to render (meaning you have no inspection of transient state, like current dom, time, variables in other services/models at time of render etc.) Third, I assume you would have a shared tracked view version - you dropped the aside and footer shared part in your simplification. Fourth, you're combining the registering child view with the attaching it to the DOM. This probably was an easy step for you because in attachView we already register the child view. But, it's important to realize and make obvious that a child view can be registered and bound to a parent without having to tie it to the parent's DOM. There's a big shift here from making rendering choices inside the render process, and making them before the rendering process. I think you, Ben, like the idea of making some of those choices decoupled from the rendering process, because it feels better to be making what seem like more semantic choices in the methods that pertain to hiding/showing method rather than to set variables and wait until the next render. I also think this is a useful addition. What I fear is this is a simplification of the process (based on the above mentioned assumptions). It would be nice if we could add additions that simplify common processes that don't restrict complicated cases and if possible highlight the process that happens under the hood, not hide it. All that said, I'd like to see if we can play with your idea to get show/hide to work while maintaining the ability to control the rendering logic if need be. |
From my conversation with @pepperbc. These are the problems/issues that are causing a need for change:
|
I like the idea of helper methods that augment instead of replace the existing functionality. Personally I'd like to keep the attach view logic in the same place, but add helpers for show/hide. The main benefit I see is adding a streamlined mechanism for show/hide that bundles the listeners and view state property setup. But even as I'm saying this I realize it all makes sense when you've worked with Torso, but makes what is happening under the hood opaque to people who are not familiar with it. My first instinct is to add helper methods that do the same setup we do now:
I'm not sold on the api above, just thinking through an alternative (and this mirrors form and object model tracking so there is some consistency in API). Configuration Options:
Automatically generated functions that you can use and reference: |
the API above changed a lot while I was writing it and it lost some of my thoughts from the first paragraph... I'm not entirely sure I like the abstraction, but it does let us configure views in a more concise way. We could also have shortcut or overloaded methods for common use cases (like the form model tracking API). |
In terms of making what's happening under the hood opqaue, I feel like all of these (including the current implementation) are difficult to see the inner workings through - without knowing Torso pretty well, you're just going to be guessing anyhow. 99% of times we're going to be using the basic cases anyhow, so the edge cases just need to be possible and documented, but not necessarily as intuitive as the standard cases (though obviously both is preferred). @mandragorn Are the changes in that API :
How do you feel about breaking your subview objects into an array? Then the initialize method could just be for actual initialization, and not configuration as well. I feel that would promote readability in a lot of classes. I made a couple of other minor API changes. There's still a few issues with this way, but I like the readability:
|
(In the car on my phone) On Thu, Apr 7, 2016, 10:39 AM pepperbc [email protected] wrote:
|
Initializing in initialize and then grabbing from the config I still find a bit awkward (as in aside and footer above). Agree that the static initialization is rarely going to be useful. I think you should be able to declare everything at the class level - I could see all of the options being valid as functions, so more complex logic is possible (either switching out the views or switching out the injection point) |
crazy thought: what if you used the alias as what to grab off the view?
Obviously, after thinking this through a bit, setting the views like this doesn't trigger anything and therefore doesn't rebind the "tracked" part until a re-render. But, I did like the feel of it. |
We could follow a similar API as adding form model tracking (again thinking to keep this type of API consistent) and allow you to separate configuration (via alias) from setting the view. I would expect 2 available ways to configure this (similar to form model binding):
The configurations above can define the view, but you can also change which view is associated with an alias (or initialize it to begin with) using an associateChildView() method (or an overload of configureChildView()?). configureChildView() would go through the same process of determining the polymorphism that we did for #209. |
Agree - anything that uses configuration at the class level should be overrideable programatically. Though I would find it awkward for the simple case if I had to specify the alias/injection point at the class level, and then set it in initialize as well. The class level wouldn't really be providing any additional information. |
you wouldn't need to do both. Generally you would do one or the other. And the simple case should still be simple:
That is what I mean by polymorphism and following the process we did for #209 where we came up with what were the most common use cases and made them easy to configure. In all cases you can pass in the same configuration you would define at class level as a configuration object to configureTrackedView(configuration); I think for this case the main use cases we need to configure are (please suggest more and better suggestions if you have them - I'm specifically optimizing brevity for common cases below):
What are other common cases? Does it make sense to always return the alias when calling it programatically and generate it if one isn't specified? |
A point of potential confusion: does a view function get evaluated once or every render. If you're switching between views in the same injection point you'd want every render. But if you wanted to instantiate things there, you'd only want once. I think it should only be evaluated once, and if you want to switch every render, you could put that sort of logic in preRender() |
When creating child views, it is a common pattern to initialize the child view in one place, and then inject it in "attachTrackedViews". This could be simplified by always injecting child views unless they have been hidden/turned off/etc. If the child view to be attached a certain injection point is to be redefined, it would only have to be redefined once, and then would always render with the new child. This would reduce boilerplate injections in the render() method, and also reduce boilerplate hide/show methods on Views.
Potential API:
intialize: function() {
this.attachChildView('my-child-view', new ChildView());
}
hideChild: function() {
this.hideChildView('my-child-view');
}
showChild: function() {
this.showChildView('my-child-view');
}
setChild: function(childView) {
this.attachChildView('my-child-view', childView);
}
The text was updated successfully, but these errors were encountered: