There are four binding modes in Aurelia as documented:
.bind - Uses the default binding. One-way binding for everything but
form controls, which use two-way binding.
.one-way - Flows data one
direction: from the view-model to the view.
.two-way - Flows data
both ways: from view-model to view and from view to view-model.
.one-time - Renders data once, but does not synchronize changes after
the initial render.
I'm looking for a .one-way binding but the other way around, with the data flow from view to view-model. My use-case is dirty-bit where you want to know when the view is dirty.
ValueConverters are bidirectional and could possibly be an OK workaround until it is implemented as described in the issue Jeremy linked to.
http://aurelia.io/hub.html#/doc/article/aurelia/binding/latest/binding-value-converters/1
you can use attribute.from-view="variable" for a one way binding from view to viewmodel
https://github.com/aurelia/binding/pull/618
Related
I've implemented data binding and view model in my app, everything works great but I face a dumb issue which actually makes me wonder about re usability.
I have a fragment which has a picture and a title from a database that I put in other fragments. It's all bind to the viewModel calling some getters.
My issue is I need it in another activity now which has a different viewmodel for clarity and also because I don't need all the livedata from before but I can't really give it the new viewmodel since when I define it the type is specific to the other one.
<variable
name="viewModel"
type="com.example.thegreenstring.view.ObjectiveViewModel" />
So what am I suppose to do? It kind of means that you can't reuse fragments unless you have the same view model right? Sucks a little. I thought the only workaround was to make a specific view model for this fragment but it feels a little weird no?
Thanks for your help in advance !
In a Cocoa application is there a standard pattern for keeping UI and other element states in sync? For example I have the main Menu managed by one class and a toolbar managed by another. Some of the menu items must reflect current selections in the toolbar and vice versa. I was going to handle this by having the selector triggered by the menu items and toolbar items fire off a Notification. The controlling classes would subscribe to these an update the UI to match the selection. Is this a good way to do this or am I missing some other natural way to do this in Cocoa?
For the specific case of whether an item should be enabled or disabled, that should be left to the target (or the implicit target if the target is the first responder). It should use User Interface Validation for that.
Bindings is another good technique. The state which governs the UI should either be in the model or the controller, and the UI should bind to it. (If the UI is to bind to the model, it should be through the controller.) That way, you only have to make sure the state is up-to-date and consistent and everything else happens automatically.
But then the technique you describe is a good third option. The model should provide notifications (through NSNotifications or a delegate) to the controller layer when it has changed. The controller layer watches those and has intimate knowledge about what effect state changes should have on the UI and explicitly configures the UI to conform.
If I changed my NSOutlineView from using bindings and an NSTreeController to having a data source and a delegate, how would I automatically update the NSOutlineView, if my model tree changes? Should I observe the childNodes property of every single node in my tree with my controller and trigger a reload when a change occurs? Or is there another way?
That's one way. Another way would be for the model to post notifications when it changes and have your controller observe those.
Also, a model doesn't typically change spontaneously. Usually, the change is initiated outside of the model in response to some event. A controller is usually doing that. So, that controller could also provoke an update to the outline view. (There may be multiple controllers, so maybe the controller that initiates the model change just informs a window or view controller, which would be responsible for updating the outline view.)
I asked a similar question that was marked as duplicate here: Recommended Pattern for Observing Changes in Tree Structure [duplicate]
I wanted to avoid using NSTreeController as it means you lose control of animations when updates occur.
I have an MVVM set up. My model is a graph, my view model is a tree. There is a one-one relationship between any tree nodes and a graph node. As detailed in the question above, there is obviously a many-one relationship between the tree nodes and an outline view.
So, I settled with...
The view-model tree nodes need to know when their children are updated, so I used KVO of the associated graph node to catch when children are added or removed.
For the outline view update I settled on a model-view delegate that I implement on the view-controller. Each tree-node in the view model can call delegate methods on the tree root when children are added or removed. This felt the clearest approach to me, and easily debuggable. I didn't want chains of things happening behind the scenes.
The final outline view update call felt satisfyingly simple:
func itemsInserted(atIndexes indexes: IndexSet, forParent parent: ECViewModelNode) {
outlineView?.insertItems(at: indexes, inParent: parent, withAnimation: .slideDown)
}
At the table-cell-view level I bind directly to the details of the graph model nodes.
I have more than one PasswordBox on my view and I want to pass all their SecureStrings to my view model when I click a button.
My guess is that I want to populate an instance of a custom class with all the SecureStrings and pass that object as a parameter to the RelayCommand bound to the button.
If I only knew how...
My current idea for a work around:
In the RelayCommands action for the button: send out a NotificationMessageAction with a callback taking a custom class as parameter.
Register for that message in the views code behind, and then populate an object with the SecureStrings, and then pass that object back to the view model with the help of the callback. Not very nice...
There must be a better way to do this in XAML, right?
Actually, I think what you want to do is implement event handlers, or an attached behavior on your PaswordBoxes that will push the SecureStrings to properties in the same viewmodel object that will be handling the RelayCommand's action. Then your RelayCommand won't need any parameters at all.
Heys,
I am writing something in Xcode. I use Core Data for persistency and link the view and the model together with Cocoa Bindings; pretty much your ordinary Core Data application.
I have an array controller (NSArrayController) in my Xib. This has its managedObjectContext bound to the AppDelegate, as is convention, and tracks an entity. So far so good.
Now, the "Content Set" biding of this NSArrayController limits its content set (as you'd expect), by a keyPath from the selection in another NSArrayController (otherAc.selection.detailsOfMaster). This is the usual way to implement a Master-Detail relationship.
I want to variably change the key path at runtime, using other controls. This way, I sould return a content set that includes several other content sets, which is all advanced and beyond Interface Builder.
To achieve this, I think I should bind the Content Set to my AppDelegate instead. I have tried to do this, but don't know what methods to implement. If I just create the KVC methods (objectSet, setObjectSet), then I can provide a Content Set for the Array Controller in the contentSet method.
However, I don't think I'm binding this properly, because it doesn't "refresh". I'm new to binding; what do I need to implement to properly update the Content Set when other things, like the selection in the master NSArrayController, changes?
However, I don't think I'm binding this properly, because it doesn't "refresh".
This most often means you are assigning directly to the instance variable, not using KVC-compliant accessor methods nor posting KVO notifications.
The general solution is to create accessor methods for the property and then use them everywhere, including inside that class, except in its init and dealloc methods.