Connect two NSObjectControllers within a multi view OSX Storyboard - macos

I'm using Storyboards for the first time creating a master/detail view for a simple object.
Both view controller items of the split view have their own view & NSObjectControllers. The controller for the table view is a NSArrayController (which shows all instances of the Entity). The controller for the detail view is an NSObjectController, which shows just the selected instance.
When I click an object in the table, I'd like the detail to show up in the detail view. So I believe my goal here is to bind the 'contents' of the detail object controller to the 'selection' of the master array controller. However with storyboards I cannot cross view controller boundaries (can't create the IB 'link'. aka: can't bind cross VC).
Whats the best practice for doing this?
So far all I can think to do is manually set all this up in one of the controllers (either the root controller, window controller or perhaps the master table view controller) - but that seems counterintuitive. That seems to defeat the purpose of being able to lay out this stuff within storyboards in the first place, and my controller of choice would then have to know about the other controller specifically.
I must be missing something!

Related

Laravel multiple model bound forms in a parent view

The overall concept that I'm attempting to do is create admin panel that has multiple "forms" on a single blade view. Each "form" is a blade.php file that has a form that is model bound to provide quick access to the model data on load. For example, let's say that I'm running a manufacturing line and there are three models (subviews) that I want to #include() on manufacturing.blade.php.
Parent view (manufacturing.blade.php)
Subview - Start time (start-time.blade.php)
Subview - Throughput (throughput.blade.php)
Subview - Supervisor (supervisor.blade.php)
Each subview has a submit button on it that POSTS to the assigned resource controller. My problem is how do I successfully load manufacturing.blade.php and include form model binding when I never call the index controller on the subviews.
Is what I'm asking even possible?
For what it's worth I figured it out right after I posted the question. The variables required for the model binding inside the subviews were the problem. I was receiving errors about the variables not available, blah.... when I loaded the parent view page. Obviously the variables aren't available when I call the subviews because they were never pulled in from the parent view. In other words I'm trying to access something that isn't there.
Solution:
In the parent view loading controller, perform all the necessary db call to obtain/generate the objects required for the subviews. After the objects are obtained use
View::share('startTime', $startTime);
View::share('throughput', $throughput);
View::share('supervisor', $supervisor);
That method (view::share) allows that variable, 'startTime', etc..., to be shared across all the blade views that reside inside of parent. Just be sure you add the lines right before you return the intended parent view from your controller.

Best practice for setting a data source and delegate for a UITableView

This question may not have a straight answer, but I am curious as to what others think. I have a UIViewController and inside that I have 2 objects a UIView and and UITableView. Each object as it's own custom class. My question is about the UITableView, what object should be the datasource and the delegate. Right now I have the UIViewController set to those rolls, but is it beset practice to set the object itself to be the data source and the delegate, maybe use the method awakeFromNib to set those 2 sources. Are both ways ok? I would think that setting the data and the delegate to the class that represents the tableview would keep that code apart from the view controller, which I would think would be a good thing.. but maybe not...
Good question actually.
Look at the Controller as an example of the Mediator Pattern from the Gang of Four: it's mediating the relationship between the View and the Model. Most of the web world has gone to using binding of some sort, so you typically see model objects 'bound' directly to the view layer, e.g. a text edit field might have an expression indicating which field in the domain object it is editing, then the framework will provide the services of marshaling and unmarshaling that data.
In Cocoa, you typically don't do that: you bind to properties in the Controller, and those typically are then used to transform the underlying domain class. So for instance, if you make a storyboard and make a form and have a custom controller, now you want to edit the name of some entity, e.g. User, you would CTRL-drag from the edit box over to the source, it would make an outlet, which would then give you control not only of what appears in that box, but the control itself. Then you could add a submit button and CTRL-drag to create a method, for Save, and when that's clicked, you could update the underlying User instance.

What all things can be stuffed inside a controller in MVC?

I was going through the articles describing the MVC pattern. None of them were clear on explaining the role of Controller in MVC. Some says Controller can make changes to the view such as disabling a button or changing the text color whereas some says any changes to the view should be done inside view only. Can you please give me tips on the following question?
1) Can any change pertaining to the view be done inside the controller?
2) What not should be written inside a controller?
3) It is right to say "View should do all the changes by itself when a new recordset is generated by the model, as the view queries model directly, and controller is not involved in this transaction?"
4) I have heard this statement about MVC "In current version of windows application development. View is capable to handle the event(like button press) and the controller is called when needed.It is stupid to delegate the event listening to the controller now." Doesn't this sound more like a MVP?
Thanks. Hoping to get some help here.
In my opinion:
1) The controller changes the data provided to the view, so in a way, yes. The view should just manage the presentation of the data provided to it by the controller.
2) The controller should contain all code to handle any actions taken by the user. Depending on the size of your application, the controller can hand the action off to a business layer to do the work then gather view data once the business layer is complete and hand it back to the view. Or, if you don't have a business layer, it can do the work directly.
3) In true MVC, the view should not have access to the model directly. The controller should create view objects from the model and pass them to the view. In any case, the view should never do any real work other than presentation.
4) I don't know MVP so cannot answer this question.
1) Controller responsibility is primarily "execute an action, choose an appropriate view, provide some data to that view and return the view to a user".
2) As MVC tries to separate presentation logic and UI rendering, I believe, controller shouldn't attempt to perform any of view responsibilities: listening to UI events or pre-formatting of values dateString = data.ToString('YYYY-MM') - that's all should go to view.
3) in MVC view knows all about a model - model is rendered by view without any controller involvement (that's primary 'issue' fixed by MVP, where view should and model should unbound as much as possible). However it's not recommended for view to query model directly. Instead, all data changes should be reported to view by model using Observer pattern.
Consider the following -
schema from wikipedia article - dashed line from model to view indicates that fact. Just keep in mind that model is more viewmodel here and shouldn't really be a part of BL layer.
So here scenario could be the following:
User clicks "add item"
View sends request to the controller with the item data
Controller makes call to BL, which makes changes to the model (adds new item to the list).
Model fires "updated" event to the view (or "error" event, if there are some issues in underlying layers)
View updates UI according to changes reported.
4) The statement is perfectly true. In MVC you shouldn't do that. I assume, in MVP you shouldn't do that as well - I mean, listening to events from UI directly. That should be done either by forwarding event by view; or using a platform-independent view representation, like
inderface IMyGridView
{
event ItemEvent AddItemClick;
}
(which doesn't make sense for MVC, as view is pretty much independent from a controller and mostly all view actions are result in calls to controller).

Switching between NSViewControllers

I'm developing a Mac Application. The application has a common source view on the left and a detail view on the right which is the main part of the whole window.
It's like a Master-Detail relationship, but each element in the source view require another detail view. In fact, I have designed a specific NSViewController for each element in the source view.
If I'm switching between these NSViewControllers, that means If I select another element in the source view, I remove the current view and add the view of the newly selected NSViewController. Everytime I change the NSViewController, its state will be lost. When the user comes back to that NSViewController, he has to start over.
My question now is: How can I save the state of the NSViewController, so that I can switch between these without losing its states and can continue where I have left?
Two considerations about your problem:
Keep model data in model classes. This means that you can always recreate a view controller and set its represented object provided the model classes have kept the changes made via the view controller. When you need to instantiate a view controller, set its represented object to (a representation of) a model class.
When removing a view from its superview, you do not necessarily need to release its corresponding view controller. Instead, you can keep strong references to all view controllers in your window controller/application delegate, so no state is actually lost.
Use NSArchiver. Implement archiving/unarchiving in your dealloc/init methods and store each view controller's state in a file named after the class (if you have one item per view controller policy). Otherwise think of some simple naming convention and use it.

Binding to a NSViewController's representedObject

(Abstract: bindings work in code, but not in IB)
I have a window managed by a NSWindowController. To the left of the window is a source view. To the right is a table view showing the elements of the currently selected source.
I have set up a NSTreeController within my window XIB. I want its contents to be used for the source view. It's selection will drive the table view.
I am trying to split this up using NSViewControllers. One view controller will load a NIB containing the source view. Another view controller will load the table view.
Seeing that I need access to the NSTreeController within the source view controller, I have set it to be the view controller's representedObject. (Actually for this setup to be done by the time awakeFromNib is called on the view controller, I have turned representedObject into an IBOutlet).
All works fine when I wire my source view up in code:
[outlineView bind:#"content"
toObject:sources
withKeyPath:#"arrangedObjects"
options:nil];
[outlineView bind:#"selectionIndexPaths"
toObject:sources
withKeyPath:#"selectionIndexPaths"
options:nil];
[[outlineView tableColumnWithIdentifier:#"Title"] bind:#"value"
toObject:sources
withKeyPath:#"arrangedObjects.title"
options:nil];
I am however unable to reproduce this using Interface Builder. Thing is, here the "controller key" textfield is grayed out. Thus I bind column's "value" to the file owner using a model keyPath of "representedObject.arrangedObjects.title". This does not show the desired behavior. Actually an exception is thrown: -[NSProxy doesNotRecognizeSelector:_mutatingNodes] called!
How can I use representedObject in IB?
Can I create a controller in IB which acts as proxy to representedObject?
Could I set-up a tree controller in the source view XIB which during NIB loading gets swapped out for the representedObject?
I moved away from using representedObject. It appears that is meant only for model objects.
I now pass in my tree controller using a custom outlet. I continued setting up and tearing down the bindings in code.
I’ve similar issues when I try to pass a reference to an object controller (NSTreeController in my case). I don’t think this is how Apple wants you to use their KVO-compatible controllers. The exceptions look like they’re XIB-unarchiving & timing-related.
The trick is not to pass the controllers, but to pass the underlying data and keep the selection in sync.
This way you can set up your bindings in a storyboard and won’t get any exceptions. You’ll have to set up a new instance of an object controller for every child view controller (copy & paste in Storyboard once you configured the first one works). For a detailed example take a look at another answer that gets much more into detail.

Resources