Skip to Content

Including XML-Fragment into HTML-View

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

Add a comment
10|10000 characters needed characters exceeded

Assigned Tags

Related questions

1 Answer

  • Best Answer
    Posted on Aug 17, 2016 at 05:24 PM

    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.


    1.jpg (103.3 kB)
    2.jpg (35.3 kB)
    3.jpg (41.1 kB)
    4.jpg (39.2 kB)
    5.jpg (19.9 kB)
    6.jpg (9.9 kB)
    7.jpg (27.5 kB)
    Add a comment
    10|10000 characters needed characters exceeded

Before answering

You should only submit an answer when you are proposing a solution to the poster's problem. If you want the poster to clarify the question or provide more information, please leave a comment instead, requesting additional details. When answering, please include specifics, such as step-by-step instructions, context for the solution, and links to useful resources. Also, please make sure that you answer complies with our Rules of Engagement.
You must be Logged in to submit an answer.

Up to 10 attachments (including images) can be used with a maximum of 1.0 MB each and 10.5 MB total.