8

Using OpenUI5/SAPUI5, per documentation on XML Binding Expressions, we have the ability to execute a function from the view.

new sap.m.CheckBox({
    selected: "{= checkSelectedItems(${odata>CustomerId}) }"
})

In my controller behind the view:

checkSelectedItems: function(sCustomerId) {
    return true;
}

In my view, I get the generic error as if it cannot find my function:

Uncaught TypeError: Cannot read property 'apply' of undefined

I've tried calling the function in several ways:

{= .checkSelectedItems() }
{= my.namespace.checkSelectedItems() }

I even tried adding a function in a script tag in my index page to see if it only has access to global functions, but I wasn't able to trigger that either. Suggestions? Am I misinterpreting the documentation?

Please see the JS Bin here : http://jsbin.com/sosotacihi/edit?html,output. I've commented out the CheckBox that has the issue, but if you put it in, you'll see the error.

mitch
  • 985
  • 10
  • 12
  • 1
    I've made slow progress, apparently the proper way to call a function is like `{= f(checkSelectedItems, null, ${odata>CustomerId}) }` where the first parameter of `f()` is your function name, second is formatter functions for your parameters, and third is an array of the parts to pass into your function. I'm still struggling with an undefined function though. – mitch Jul 24 '15 at 18:08

3 Answers3

3

You need to use formatter to call methods of controller from an XML View.

 new sap.m.CheckBox({
     selected: "{parts:['odata>CustomerId'], formatter:'.checkSelectedItems'}"
 });

This can be applied to any event triggering attribute. The generic way to mentioned this is:

{parts:['<parameter1>', '<parameter2>', ...], formatter:'.<methodInController>'}
3

To reuse a controller function in an expression binding, the complex binding syntax works there as well:

selected="{= ${parts: [{path: 'myModel>property'}], formatter: '.myMethodInController'} === 'foo'}"

Currently, it only works when parts:[{path: ...}] is included. But of course, just because it works, doesn't mean we should use it. As you can see, such an expression binding can become quickly unreadable.
UI5 suggests to stick with a formatter function if the expression binding gets hard to read.

We recommend to use formatter functions instead of very complex and hard-to-read expressions.

Check out this documentation.


The syntax someFn(...) in an expression binding works only if someFn is one of the global symbols, such as Math.max(...) or isNaN(...).

Boghyon Hoffmann
  • 17,103
  • 12
  • 72
  • 170
-1

UI5 Suggests to use Expression Binding instead of formatter functions. The Expression binding is mainly for XML views not for JS views.

  • The expression binding is still rendered and executed in the view, regardless if it was set in JS or XML. Also, how is the above not an expression binding? – mitch Jul 24 '15 at 21:05
  • Not sure, what you mean by executed in the view ? – Sarath Chandra Jul 24 '15 at 21:48
  • Assume that I declared the ComboBox in the XML instead of JavaScript like you see above. Does that change your answer at all? – mitch Jul 24 '15 at 21:58
  • To call formatter functions in Js and XML we have certain place holders for them like formatter=".onPress". If you want to handle whole logic within binding expression then we can go with XML Expression binding. Hope I answered your question. – Sarath Chandra Jul 24 '15 at 22:04
  • I've updated my question to include a JS Bin. I've shown it using XML, and illustrates what my goal is. Hopefully you can take a look and can provide some advice. – mitch Jul 24 '15 at 22:34
  • I'm sorry, Now I got your question completely....I'm trying to figure out how to call function from Expression binding....... – Sarath Chandra Jul 25 '15 at 21:55
  • I did not work with expression bindings so far, but I fear that this cannot work as you're using an anonymous controller which is not made available on the global namespace which would be required to call a function on it. I will check if I'm able to build up an working example. – matbtt Jul 27 '15 at 20:14
  • The following link will help you a little bit https://github.com/SAP/openui5/blob/ae51c36f2c7c200d71919cf17f1ea5607f94f05a/src/sap.ui.core/test/sap/ui/core/qunit/ExpressionParser.qunit.js . I tried to develop some example but still not successfull. – Sarath Chandra Jul 27 '15 at 22:28
  • Thanks, everyone. @SarathChandra, I had looked at that ExpressionParser in order to determine how it deals with functions. That's how I found I could include function name, formatters, and parameter lists. Unfortunately, I was still seeing undefined on the function call. Putting a breakpoint in the ExpressionParser definitely helped me get farther. – mitch Jul 29 '15 at 17:44
  • @matbtt, although I have an anonymous controller in JSBin, I used sap.ui.define() for my controller in my real-world example, but I'm still unable to get my function called. For right now, I'm using a formatter function, but it feels wrong for how I'm using it. – mitch Jul 29 '15 at 17:45
  • @mitch Just as a side note: UI5 does not always recommend to use Expression Binding: "We recommend to use formatter functions instead of very complex and hard-to-read expressions." ([src](https://ui5.sap.com/#/topic/daf6852a04b44d118963968a1239d2c0)) – Boghyon Hoffmann Nov 20 '17 at 10:12