Make it easier to setup 2-way-binding and other interesting behaviors #178

Closed
justinbmeyer opened this Issue Nov 28, 2012 · 7 comments

Comments

Projects
None yet
3 participants
@justinbmeyer
Contributor

justinbmeyer commented Nov 28, 2012

Create an easy way to setup 2-way-binding and other behaviors.

2-way-binding

<input value="{{name}}"/>
// registers a callback for when an attribute is matched
can.view.attr("value", 

// callback is called during parsing and "function" generation.
// this gives the user the ability to edit the compiled function
// scanner - the scanner ... allows us to modify the generated "function"
// contents - "{{name}""
function(  scanner, contents ) {

  // registers a callback to run after the before attribute code
  // callback is called during rendering
  scanner.before(function(template){
    // template might provide helpers to turn {{name}} into 
    var propName = template.getProperty(contents);

    // template might provide helpers to get the current context
    var context = template.getContext()
    // registers a callback to run once the element 
    template.hook(function(el){

      can.bind.call( can.$(el), 'change', function(){
        context.attr(propName, el.value )
      })
    })
  })


  // can modify the template if necessary, not necessary here
  return contents;
})
@justinbmeyer

This comment has been minimized.

Show comment
Hide comment
@justinbmeyer

justinbmeyer Nov 28, 2012

Contributor

Something like: scanner.before(function(template){ can't work with loading pre-processed templates. We would only be able to return a string. Thus, it might work more similar to:

// registers a callback for when an attribute is matched
can.view.attr("value", 

// callback is called during parsing and "function" generation.
// this gives the user the ability to edit the compiled function
// scanner - the scanner ... allows us to modify the generated "function"
// contents - "value='{{name}'"
function(  scanner, contents ) {

  if( contentsHasATemplate ) {
    // insert needs to close _v1ew.push
    scanner.insert( "can.view.twoway.value( template, "+contents+");"
  }
  // can modify the template if necessary, not necessary here
  return contents;
})

can.view.twoway.value = function(template, contents){

    // template might provide helpers to turn {{name}} into 
    var propName = template.getProperty(contents);

    // template might provide helpers to get the current context
    var context = template.getContext()
    // registers a callback to run once the element 
    template.hook(function(el){

      can.bind.call( can.$(el), 'change', function(){
        context.attr(propName, el.value )
      })
    })
}

There's probably a way to pretty this up ...

Contributor

justinbmeyer commented Nov 28, 2012

Something like: scanner.before(function(template){ can't work with loading pre-processed templates. We would only be able to return a string. Thus, it might work more similar to:

// registers a callback for when an attribute is matched
can.view.attr("value", 

// callback is called during parsing and "function" generation.
// this gives the user the ability to edit the compiled function
// scanner - the scanner ... allows us to modify the generated "function"
// contents - "value='{{name}'"
function(  scanner, contents ) {

  if( contentsHasATemplate ) {
    // insert needs to close _v1ew.push
    scanner.insert( "can.view.twoway.value( template, "+contents+");"
  }
  // can modify the template if necessary, not necessary here
  return contents;
})

can.view.twoway.value = function(template, contents){

    // template might provide helpers to turn {{name}} into 
    var propName = template.getProperty(contents);

    // template might provide helpers to get the current context
    var context = template.getContext()
    // registers a callback to run once the element 
    template.hook(function(el){

      can.bind.call( can.$(el), 'change', function(){
        context.attr(propName, el.value )
      })
    })
}

There's probably a way to pretty this up ...

@justinbmeyer

This comment has been minimized.

Show comment
Hide comment
@justinbmeyer

justinbmeyer Nov 28, 2012

Contributor

Another example ... hooking up a control:

<div data-control='controls/widget'
   data-control-args='customer, name:fullName'>
can.view.attr('data-control', function(scanner){

  scanner.insert("can.view.toway.control( template, "+contents+")")

  return; // no need to add the attribute
})
can.view.attr('data-control-args', function(scanner, contents){
  scanner.insert("can.view.addData("+contents+")");
})

can.view.toway.control = function(template, contents){
  var control = require(contents);
  template.hook(function(el, data){
    new control( el, data['data-control-args'] );
  })
}

can.view.toway.addData = function(template, contents){
  // break up contents and lookup
  template.elementData("data-control-args", DATA );
}
Contributor

justinbmeyer commented Nov 28, 2012

Another example ... hooking up a control:

<div data-control='controls/widget'
   data-control-args='customer, name:fullName'>
can.view.attr('data-control', function(scanner){

  scanner.insert("can.view.toway.control( template, "+contents+")")

  return; // no need to add the attribute
})
can.view.attr('data-control-args', function(scanner, contents){
  scanner.insert("can.view.addData("+contents+")");
})

can.view.toway.control = function(template, contents){
  var control = require(contents);
  template.hook(function(el, data){
    new control( el, data['data-control-args'] );
  })
}

can.view.toway.addData = function(template, contents){
  // break up contents and lookup
  template.elementData("data-control-args", DATA );
}
@whitecolor

This comment has been minimized.

Show comment
Hide comment
@whitecolor

whitecolor Dec 13, 2012

Contributor

Is two way binding going to be supported in EJS?

Contributor

whitecolor commented Dec 13, 2012

Is two way binding going to be supported in EJS?

@jeffrose

This comment has been minimized.

Show comment
Hide comment
@jeffrose

jeffrose Dec 14, 2012

I would hope the two way binding is agnostic of the view engine.

I would hope the two way binding is agnostic of the view engine.

@justinbmeyer

This comment has been minimized.

Show comment
Hide comment
@justinbmeyer

justinbmeyer Dec 14, 2012

Contributor

Unlikely. How a value is specified works differently in EJS vs mustache.

Sent from my iPhone

On Dec 14, 2012, at 4:18 PM, Jeff Rose notifications@github.com wrote:

I would hope the two way binding is agnostic of the view engine.


Reply to this email directly or view it on GitHub.

Contributor

justinbmeyer commented Dec 14, 2012

Unlikely. How a value is specified works differently in EJS vs mustache.

Sent from my iPhone

On Dec 14, 2012, at 4:18 PM, Jeff Rose notifications@github.com wrote:

I would hope the two way binding is agnostic of the view engine.


Reply to this email directly or view it on GitHub.

@whitecolor

This comment has been minimized.

Show comment
Hide comment
@whitecolor

whitecolor Dec 15, 2012

Contributor

Then, it seems that guys from bitovi talked about some plugin for two-way form binding.

Contributor

whitecolor commented Dec 15, 2012

Then, it seems that guys from bitovi talked about some plugin for two-way form binding.

@justinbmeyer

This comment has been minimized.

Show comment
Hide comment
@justinbmeyer

justinbmeyer Sep 20, 2013

Contributor

can.Component branch offers everything this needs.

Contributor

justinbmeyer commented Sep 20, 2013

can.Component branch offers everything this needs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment