BorisMoore / jsviews

Interactive data-driven views, MVVM and MVP, built on top of JsRender templates
http://www.jsviews.com/#jsviews
MIT License
855 stars 130 forks source link

Two way data binding through string paths #327

Closed markibanez closed 8 years ago

markibanez commented 8 years ago

Hi @BorisMoore,

I was wondering if it was possible to do two-way data binding using string paths.

If we had the following object model:

var model = {
   a: { 
      b: 'c.d'
   },
   c: {
      d: 'databound value'
   }
};

What I want to achieve is to use model.a.b to bind to c.d. I admit the logic may look silly, but I plan on using it in conjunction with the {^{for}} tag to dynamically bind values.

Thanks.

BorisMoore commented 8 years ago

Sorry - I missed replying to this.

Well there are a few ways you can do that, but here are two: write a converter, or write a custom tag - in each case using a function to get the data based on the path. (You could replace the eval code by something better and more secure).

<script id="myTmpl" type="text/x-jsrender">
  <input data-link="a.b"/>

  {^{atPath a.b}}
    <input data-link="name"/>
  {{/atPath}}

  {^{for ~atPath(a.b)}}
    <input data-link="name"/>
  {{/for}}
</script>
var model = {
  a: { 
    b: 'c.jo'
  },
  c: {
    jo: {name: "Jo"},
    jeff: {name: "Jeff"}
  }
};

function getDataFromPath(path) {
  return eval("model." + path);
}

$.views
.tags({
  atPath: {
    baseTag: "for",
    render: function(val) {
      return this.base(getDataFromPath(val));
    }
  }
})
.helpers({
  atPath: getDataFromPath
});

 $.templates("#myTmpl").link("#tabsView", model);

If you change the input text box from "c.jo" to "c.jeff" you will see the custom "{{atPath}}" tag and the {{for ~atPath()}} will move their context to "c.jeff" and show the correct name.

I created a jsfiddle here: http://jsfiddle.net/BorisMoore/ojnzohjx/

BorisMoore commented 8 years ago

Another approach would be to use dynamic linking based on expressions - as in the following example: https://github.com/BorisMoore/jsviews/issues/311#issuecomment-143846808 http://jsfiddle.net/BorisMoore/hqy06tm5/

markibanez commented 8 years ago

Awesome! Thanks @BorisMoore