cancel
Showing results for 
Search instead for 
Did you mean: 

Including XML-Fragment into HTML-View

MelinaLuciaAlt
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hey everyone,

I have an issue while implementing SAPUI5 and I could not find an answer on the internet.

Maybe someone here can help me

It's the following problem:

I have a fragment, written in XML (Head.fragment.xml) and a view, written in HTML (Overiew.view.html).

The other views I have are written in XML and there I can include my fragment with

<mvc:View>

  <Page>

  <headerContent>

  <core:Fragment fragmentName="xy.view.Head" type="XML"/>

  </headerContent>

  </Page>

</mvc:View>

But how can I include it in an HTML-View?

I tried

<div data-sap-ui-type="sap.m.App">

<div data-sap-ui-type="sap.m.Page">

<div data-sap-ui-type="sap.ui.core.Fragment" data-fragment-name="xy.view.Header" data-type="XML">

But I get the error "please provide a fragment name".

I still use a controller for the view, so this answer sap - Using html fragments with declarative html views - Stack Overflow didn't work for me.

Thanks in advance for every answer!

Melina

Accepted Solutions (1)

Accepted Solutions (1)

saivellanki
Active Contributor

Hi Melina,

Yes, there is an issue when you embed XML fragment into HTML view. This is nothing to do with your code, it is something to do with the library.

Let me explain what is happening at the background.

When you use HTML view, below files are loaded from library


DeclarativeSupport.js --> basically this is the file that does the whole logic of creating controls, handling events, properties, aggregations etc., from HTML view.

And there is one more file that will load, when you use a fragment -- Fragment.js


You can see that 'fragmentName' / data-fragment-name (HTML Declarative) is not a property, but it is a special setting.


Let's come back to DeclarativeSupport.js, here you can check there is a function as _addSettingsForAttribiutes which will fetch the property and their values


    b._addSettingsForAttributes = function(s, c, e, v) {

        var t = this;

        var S = b.attributes;

        var B = M.bindingParser;

        var d = [];

        var r = /^data-custom-data:(.+)/i;

        q.each(e.attributes, function(i, A) {

            var n = A.name;

            var f = A.value;

            if (!r.test(n)) {

                if (typeof S[n] === 'undefined') {

                    n = t.convertAttributeToSettingName(n, s.id);

                    var p = t._getProperty(c, n);

                    if (p) {

                        var o = B(f, v && v.getController(), true);

                        if (o && typeof o === 'object') {

                            s[n] = o;

                        } else {

                            s[n] = t.convertValueToType(t.getPropertyDataType(p), o || f);

                        }

                    } else if (t._getAssociation(c, n)) {

                        var g = t._getAssociation(c, n);

                        if (g.multiple) {

                            f = f.replace(/\s*,\s*|\s+/g, ',');

                            var I = f.split(',');

                            q.each(I, function(i, l) {

                                I[i] = v ? v.createId(l) : l;

                            });

                            s[n] = I;

                        } else {

                            s[n] = v ? v.createId(f) : f;

                        }

                    } else if (t._getAggregation(c, n)) {

                        var h = t._getAggregation(c, n);

                        if (h.multiple) {

                            var o = B(f, v && v.getController());

                            if (o) {

                                s[n] = o;

                            } else {

                                throw new Error('Aggregation ' + n + ' with cardinality 0..n only allows binding paths as attribute value');

                            }

                        } else if (h.altTypes) {

                            var o = B(f, v && v.getController(), true);

                            if (o && typeof o === 'object') {

                                s[n] = o;

                            } else {

                                s[n] = t.convertValueToType(h.altTypes[0], o || f);

                            }

                        } else {

                            throw new Error('Aggregation ' + n + ' not supported');

                        }

                    } else if (t._getEvent(c, n)) {

                        var j = v && (v._oContainingView || v).getController();

                        var k = V._resolveEventHandler(f, j);

                        if (k) {

                            s[n] = k;

                        } else {

                            throw new Error('Control "' + s.id + '": The function "' + f + '" for the event "' + n + '" is not defined');

                        }

                    } else {}

                } else if (typeof S[n] === 'function') {

                    S[n](f, s, c);

                }

            } else {

                n = q.sap.camelCase(r.exec(n)[1]);

                var o = B(f, v && v.getController());

                d.push(new a({

                    key: n,

                    value: o || f

                }));

            }

        });

        if (d.length > 0) {

            s.customData = d;

        }

        return s;

    }

In  the above code, we are interested at line #13 i.e., var p = t._getProperty(c, n);

_getProperty function would be something like this:


    b._getProperty = function(c, n) {

        return c.getMetadata().getProperty(n);

    }

When I say c.getMetadata().getAllProperties(), I see it lists only 'type' as property.

and it doesn't show fragmentName because it is a special setting (returns undefined).

    

this is the error that you see on console


If I say, c.getMetadata().getAllSettings(), then I can see 'fragmentName':

So the issues lies here, since 'fragmentName' is not a property and it is a special setting, it is not able to pull the value and returns undefined. A workaround would be extending DeclarativeSupport.js to something like this:


b._getProperty = function(c, n){

     if(c.getMetadata().getProperty(n)){

          return c.getMetadata().getProperty(n);

     }else{

          var oSettings = c.getMetadata().getAllSettings();

          return oSettings[n];

     }

}


This will give you the result. But, ensure that you will have to point to new extended js file on HTMLView definition as well.


Hope you understood, whatever I tried to explain.

Regards,

Sai.

MelinaLuciaAlt
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hi Sai,

thanks a lot for that detailed answer, that helped me understanding why it don't work!

Regards,

Melina

ChrisSolomon
Active Contributor
0 Kudos

Wow! Great explanation! 

Answers (0)