1

I try to use the same SimpleForm for creating a new object and for editing. I try to make it this way:

<Input value="{= !${/isNew} ? ${som>Id} : ${newModel>Id}" />

But the bindings are not in mode TwoWay. Is there a possibility to make it to TwoWay Binding?

Boghyon Hoffmann
  • 17,103
  • 12
  • 72
  • 170
Flo
  • 1,179
  • 3
  • 15
  • 43
  • The simple answer is No. It is not possible. Reason being UI5 framework has to reverse engineer the logic to update the models, which would be too complex. An alternate solution would be to always bind it to newModel>Id. For edit scenario, write code to set newModel>Id = som>Id. – krisho Apr 09 '18 at 07:14
  • To extend [@krisho's comment](https://stackoverflow.com/questions/49367613/compositebinding-complex-syntax-with-twoway-binding-mode/49711462#comment86468487_49367613): No, it's not possible with *Expression Binding*. However, TwoWay binding is still possible within *CompositeBinding* when a proper `type` is given as [demonstrated below](https://stackoverflow.com/a/49711462/5846045). – Boghyon Hoffmann Apr 16 '18 at 08:17

3 Answers3

1

Cause

In a property binding, using ...

... turns the binding mode into OneWay. Unless only the path is defined in the binding info object (not parts), all the above cases make use of the module sap.ui.model.CompositeBinding.

Resolution

Expression Binding definition as it's written in the question cannot become TwoWay.

However, CompositeBinding does allow TwoWay binding by having a type to the property binding info assigned that is derived from sap.ui.model.CompositeType.

  • Use either one of the existing data type classes derived from the CompositeType (Click on "View subclasses" in the API reference)
  • Or define your own composite type class.
    • Sample Currency type definition from UI5.

    • Sample ternary type that behaves like the above Expression Binding definition: https://embed.plnkr.co/0MVvfZ/?show=view%2FHome.view.xml,preview

      It takes all three parts necessary for the ternary operation; one for the condition, one for binding the truthy case (a), and one for binding the falsy case (b):

      <Input value="{
         parts: [
           '/myTruthyOrFalsyValue',
           'a>/bindingThisTwoWayIfTruthy',
           'b>/bindingThisTwoWayIfFalsy'
         ],
         type: 'demo.model.type.MyTernary'
      }" />
      

      The actual ternary operation happens in the type definition which could look something like this:

      sap.ui.define([ 
         "sap/ui/model/CompositeType"
      ], function(CompositeType) {
         "use strict";
      
         return CompositeType.extend("demo.model.type.MyTernary", {
           constructor: function() {
             CompositeType.apply(this, arguments);
             this.bParseWithValues = true; // Publicly documented. Make 'parts' available in parseValue
           },
      
           /**
           * Displaying data from the right model (model -> view)
           */
           formatValue: parts => parts[0] ? parts[1] : parts[2],
      
           /**
           * Assigning entered value to the right model (view -> model)
           */
           parseValue: (enteredValue, stuff, parts) => parts[0] ? [
             parts[0],
             enteredValue,
             parts[2],
           ] : [
             parts[0],
             parts[1],
             enteredValue,
           ],
      
           validateValue: () => true // Nothing to validate here
         });
      });
      

Prerequisites

  • In order to allow TwoWay composite binding, all binding parts must have the TwoWay binding mode enabled:

    Note that a composite binding will be forced into mode OneWay when one of the binding parts is not in mode TwoWay. (Source: ManagedObject#bindProperty)

  • Ensure that the bootstrap configuration option sap-ui-compatVersion is set to "edge".

Boghyon Hoffmann
  • 17,103
  • 12
  • 72
  • 170
0

I am not quite sure, if using expression binding in values is the right way to do it, but should work with JSON models without additional coding (except for data-sap-ui-bindingsyntax="complex" in your ui5-bootstrap)

With a OData model you need to use oModel.setDefaultBindingMode("TwoWay") as described in Setting the Default Binding Mode since OData models use OneWay binding as default.

A.vH
  • 881
  • 6
  • 10
0

There is another way you can go about this. Make use of any of the events(ex:submit) on the Input control.

View:

<Input value="{= !${/isNew} ? ${som>Id} : ${newModel>Id}" submit="onSubmitValue"/>

Controller:

onSubmitValue:function(oEvent){
      var value=oEvent.getSource().getValue();
  var sPath=oEvent.getSource().getBindingContext('YourModelName').getPath();
 this.getView().getModel('YourModelName').setProperty(sPath+'/PropertyName',value);
}
Nguyễn Văn Phong
  • 13,506
  • 17
  • 39
  • 56