MithrilJS / mithril.js

A JavaScript Framework for Building Brilliant Applications
https://mithril.js.org
MIT License
14.02k stars 925 forks source link

Loading templates #268

Closed kevyworks closed 10 years ago

kevyworks commented 10 years ago

Hi, how can we load a mithril template from the remote view?

/remote-php/view/dashbord

m('div', 'dashboard');

client-side

m.request({ ..., deserialize: ...}).then(function(data) { m.render('.view', data); });

Cheers!

zzmp commented 10 years ago

m.render's signature calls for a DOMElement as its first argument, not a CSS-style selector. m('div', 'dashboard'); returns a JSONifiable object, which is used in the virtual diff/rendering by Mithril.

I've never worked with PHP, so I can't speak directly to this, but you'll either need to:

  1. Eval the dashboard code returned by your request (dangerous), or
  2. Execute the dashboard code on the server, and pass in the JSON object to m.render as its second argument.

Hope that helps. If not, could you include some more context?

kevyworks commented 10 years ago

The returned string from php is just the m('div', 'dashboard') obviously it didnt work. I would also like to know how to render the compiled {tag:'d'...} from remote.

here is my test:

m.request({
    url: meta.templateUrl,
    method: 'GET',
    background: true,
    /*deserialize: function (v) {
        return v;
    }*/
}).then(function (d) {
    //m.render(targetElement[0], m.trust(d));
    m.render(targetElement[0], d);
});

assuming:

d = { tag: 'div', attr: { html: 'test' } }

there should be away to do this, since mithril is something different in rendering templates from other spa frameworks.

kevyworks commented 10 years ago

hmm, ok. this works:

d = { tag: 'div', attrs: { }, children: 'a' }
kevyworks commented 10 years ago

@zzmp How do I execute a javascript code from a m.trust(remoteHtml)?

lhorie commented 10 years ago

I'm assuming you trust the code coming from the server. If so, you can build a function from the string:

m.request({
    url: meta.templateUrl,
    method: 'GET',
    background: true,
    deserialize: function (v) {
        return v;
    }
}).then(function (d) {
    m.render(targetElement[0], new Function("return " + d).call()); //becomes function() {return m("div", "dashboard")}
});
kevyworks commented 10 years ago

Hi @lhorie Is there possible way to execute script from m.trust() ?

lhorie commented 10 years ago

Browsers prevent running scripts that are injected via innerHTML and friends for security reasons (as is explained in the documentation). If you know what the script is, you can run it by calling m("script[src='the-script.js']") from outside m.trust. Otherwise you need to either use a hack like <iframe onload="..."> or manually tell the browser that you trust each script on the HTML string (i.e. query the rendered HTML for script tags, create new script tags that match them yourself , insert the new ones into the DOM, then clean them up after they run). A more convenient alternative is to use jQuery, which automatically does all that legwork for you under the hood

var trusts = function(html) {
  return function(element, isInitialized) {
    if (!isInitialized) {
      $(element).html(html)
    }
  }
}

m("div", {config: trusts("<script>alert(1)</script>")})
kevyworks commented 10 years ago

Thanks @lhorie I appreciate your help man..