This is the demo,when I click the checkbox "chooseAll",There is a warning in console,that say
Two-way binding does not work with expressions (`items.length===hasChooedItems().length` on <input>,
I change the ractive's version form "latest" to "0.6.1",when i click the "chooseAll",there is a wrong in console,that sayCannot read property 'split' of undefined. why?
The warning you get with the latest version is essentially protecting you from the error you see with 0.6.1.
Two-way binding only works with simple references (like <input type='checkbox' value='{{foo}}'>), because Ractive knows how to update its model when you interact with that checkbox, by toggling the value of foo - more complex expressions can't use two-way binding (if value='{{a || b}}', there's no way to determine whether it's a or b that should toggle, for example). So in those cases we have to listen for change events and handle them ourselves (hence on-change='toggleAll').
Older versions of Ractive would fail to recognise the problem and try to update the binding, causing that internal error. Now, you get the warning up-front.
You can either ignore it - it's harmless - or eliminate the warning by specifying twoway='false' on the input. That's equivalent to saying 'it's okay, Ractive, I got this'. Here's a fork of your fiddle with that change on line 17.
Related
I am familiar with bindings with curly braces, like {{variable}}, from Polymer 0.5.
However, in examples and code snippets for the release version of Polymer, I've begun to notice bindings with square brackets, such as [[variable]], as well.
Does {{variable}} mean something different now, or is it the same and [[variable]] is just an addition? What is the difference between binding to [[variable]] and {{variable}} in Polymer?
Just as you've noticed, there are now two different syntaxes for data-binding, which have different purposes:
{{variable}} indicates that you would like Polymer to automatically detect whether or not the binding should be one-way or two-way.
[[variable]] indicates that you want the binding to one-way only.
Why the change?
Polymer 1.x differs from older versions is that bindings are now one-way by default, much unlike 0.5, where they were always two-way.
In other words, if you write
<my-element some-property="{{myVariable}}"></my-element>
then by default, when
myVariable is changed, Polymer updates the binding, and thus updates my-element's someProperty.
someProperty is changed, Polymer does not update the binding to myVariable.
This is always the case unless you set notify:true on the property inside my-element:
Polymer({
is: 'my-element',
properties: {
someProperty: {
notify: true,
...
With notify: true, the binding is now two-way, so when
myVariable is changed, Polymer updates the binding to someProperty.
someProperty is changed, Polymer also updates the binding to myVariable.
This behaviour (when using notify: true) used to be default in 0.5; now you must ask for it explicitly.
When to use [[variable]]
There's no technical reason why you must use [[variable]], because Polymer will automatically detect whether bindings are one or two-way with {{variable}}. So why would you use it?
Let's say you're working in a large project, and you know that based on the way that data flows in a particular page/element, a certain property should never be changed by the element it is being bound to, for example in the case of an element which functionally serves a purpose as a label:
<display-data source-data="{{data}}"></display-data>
...
<data-editor source-data="{{data}}"></data-editor>
Everything looks good! The data property is bound to both the display-data element and data-editor elements, and will be automatically shared between them. (In this example, assume display-data's sole purpose is to preview the data that it is bound to.)
One day, you or someone else is editing display-data, and you forget about the situation in which it is being used in above. For an entirely different use-case, you or the other developer would like display-data to also format or otherwise modify the data it is given and push it back towards any other elements that may be bound to it. You/they edit display-data as such:
Add notify: true to sourceData, to allow two-way data-binding.
Add code into display-data which modifies the sourceData property.
This works great for all the pages that needed this functionality. But on the page mentioned before, this was not intended and ends up garbling the data that data-editor sees!
This problem would have been avoided had:
The dev team communicated better and had been more considerate of where elements are being used,
and/or [[data]] was used instead of {{data}} in the page/element in question.
With
<display-data source-data="[[data]]"></display-data>
...
<data-editor source-data="{{data}}"></data-editor>
data-editor can change data, but display-data will only ever be able to read data, and won't be able to change its value when it changes the value of its sourceData property, even when notify: true is set on sourceData.
Therefore, it could potentially be a good idea to:
Use [[variable]] whenever you need to bind to variable. This way, you enforce the direction through which data should flow in your element/page/application.
Use {{variable}} whenever you know that the binding must be two-way.
According to the documentation,
To make your code more easier to read, you may want to use the [[property]] form by default, and only use {{property}} for two-way bindings.
This being said, however, it ultimately comes down to a matter of choice. If you want to forego the use of [[variable]], no one is stopping you and you will not start any fires.
I was wondering how to bind values where the source of the bind could be null.
I have a property:
private ObjectProperty<Operation> operation = new SimpleObjectProperty<>(null);
I also have a text field:
#FXML
private Text txtCurrentOperation;
I would like to bind the textProperty of the field to the value of the operation object.
My first thought was to use FluentAPI with its when/then/otherwise construct, but it is eagerly evaluated so the solution:
Bindings.when(operation.isNotNull())
.then("null")
.otherwise(operation.get().getName()));
will throw a NPE, because the parameter of otherwise is evaluated no matter what the result of the when.
My next idea was to use lambda somehow:
txtCurrentOperation.textProperty().bind(() ->
new SimpleStringProperty(
operation.isNotNull().get() ? "Null" : operation.get().getName()
));
But the bind has no lambda enabled solution. (Later I realized that it couldn't have, becasue the real work goes backward: the change of the binded object (operation) will trigger the update of the binder (the field text property).)
Some articles I found suggested to use an "extremal" value for the property instead of null. But Operation is a complex and heavy weight component so it is not trivial to construct an artifical instance to represent null. Even more, this seems to me boilercode, something the binding mechanism is designed to help eliminating.
My next try was to logically swap the binding direction and add listener to the operation property and let it update the field programatically. It works and rather simple as long as the need of update only depends the operation object instances:
operation.addListener((e) -> {
txtCurrentOperation.setText(operation.isNull().get() ?
"Null" : operation.get().getName());
});
operation.set(oper);
It is relatively simple, but doesn't work: it throws "A bound value cannot be set." exception and I don't see why is the text property of the control regarded as bound.
I ran out of ideas. After much searching, I still cannot solve the simple problem to update a text field differently based on whether the source is null or not.
This seems so simple and everyday problem, that I am sure I missed the solution.
If a 3rd party library is an option, check out EasyBind. Try something like this:
EasyBind.select(operation)
.selectObject(Operation::nameProperty)
.orElse("null");
There's also a JavaFX JIRA issue for the type of functionality provided by EasyBind. If you don't want to use a 3rd party library, try Bindings.select:
Bindings.when(operation.isNotNull())
.then("null")
.otherwise(Bindings.select(operation, "name"));
Be aware the null checking in Bindings.select isn't super efficient. There's a JIRA issue for it.
Just in case if somebody using not Java itself but Kotlin.
It is a good idea to use wonderful tornadofx library.
There you can just use operation.select{it.name}. Although, this feature seems not to be documented yet, so it took some time to discover it.
In my main window (QMainWindow) I have a QTableView (named commandsTableView). Now I want to react on its selection changes.
I made a slot and connected it manually to ui.commandsTableView->selectionModel(). All works fine.
But then I thought: why not use auto-connection (especially that there will be more connections to be done)? At least it will add more force to consistent naming rules.
Yet I wasn't able to find proper name syntax. I tried:
on_commandsTableView_selectionModel_selectionChanged,
on_commandsTableViewSelectionModel_selectionChanged,
on_commandsTableView_selectionChanged,
on_commandsTableView___selectionChanged
but neither worked. In all cases there is there is a message on output when running the app (with corresponding slot name, here only first given as an example):
QMetaObject::connectSlotsByName: No matching signal for on_commandsTableView_selectionModel_selectionChanged(QItemSelection,QItemSelection)
(Why there are no assertions in response for connection errors - that I cannot understand. I lost much time wondering what is wrong before I spotted those - and alike - messages on output.)
The object returned by ui.commandsTableView->selectionModel() has an empty name. But setting it to selectionModel prior to making a call to connectSlotsByName doesn't help either.
According to the documentation connectSlotsByName() only supports signatures like
void on_<object name>_<signal name>(<signal parameters>);
According to the sources that's the only form it checks (watch how it collects a list of children, then matches parent's method names against names of the children).
Hence, to be able to use auto-connection you would have needed a named selection model, which would continue existing from the call to connectSlotsByName() onwards. Each time you change the selection model (not likely) or the model (likely) you'd have to name the selection model and auto-connect again. But alas connectSlotsByName() will duplicate all other connections as it doesn't seem to check if connections are unique, so we have to connect signals to such dynamic children as models, scenes etc manually.
I think it's
on_selectionModel_selectionChanged(const QItemSelection & selected, const QItemSelection & deselected)
I have an observer to a value "App.selectedValue". I also have another Ember object that has a binding (App.someObj.appValueBinding) to App.selectedValue. However, when my observer is called, the binding of App.someObj is not updated.
This is illustrated in http://jsfiddle.net/Ur2Qj/8/
In the jsfiddle, you can see in the Chrome debugger or FireBug, that App.selectedValue and App.someObj.appValue have different values, even tho' the latter is bound to the former.
Seems like the binding should be updated when the observer is called. Is this expected behavior in Emberjs or is it a bug? Is there a work-around?
Thanks for looking at this!
Take a look at this: http://jsfiddle.net/ud3323/GUHCD/ (in JavaScript; I don't like CoffeeScript... sorry).
The two main things you've got wrong here is not using get() and set() properly and in your observer you need to set App.someController.content after the end of the current runloop (which means after all the other bindings have taken place). You do this by using Ember.run.next(). You could also use Ember.run.sync() there as well.
Oh and you need to use jQuery 1.7.1. Version 1.5.2 is not compatible with Ember.
how come that when I attach onchange by attribute and call it
onchange="validateDate(FPR_CURR_FROM);"
it works, but when I use a ASP .NET validator, and my attached function is called like :
function anonymous() {
ValidatorOnChange(event);
validateDate(FPR_CURR_FROM);
}
I get error: FPR_CURR_FROM is undefined.
First off: I know that using FPR_CURR_FROM to access element is BAD, and I should use getElementByID etc... And I will change it eventually. But as I bumped into that code, I'm curious what caused it - propably visibility of variables I guess.
I think it's a scoping issue, yes, it would take seeing more code and how anonymous is called, but that is what it looks like to me from what I see... One way around that is to attach the FPR_CURR_FROM variable to the window object, and access it via window.FPR_CURR_FROM...