mbest / knockout.punches

A collection of enhanced binding syntaxes using Knockout 3+
http://mbest.github.io/knockout.punches/
238 stars 19 forks source link

ko.components params #35

Open kaleb opened 10 years ago

kaleb commented 10 years ago

Would you be interested in adding a feature to use punches style attributes on ko component params?

From:

<my-element params="foo: 'bar', baz: qux"></my-element>

To:

<my-element foo="bar" baz="{{ qux }}"></my-element>

I've not began implementing, but thought I would check here to see if there was any interest.

aminroosta commented 9 years ago

since there is no way to know if

<my-element foo={{qux}} ></my-element>

should be converted to

<my-element data-bind='foo: qux'></my-element> 

or

<my-element params='foo:qux'></my-element>

I suggest using this syntax

<my-element foo='((qux))'></my-element> 

and we can simply implement it by something like this

  var getAttributeValue = function(attr){
    if(attr.value.slice(0,2) !== '((' || attr.value.slice(-2) !=='))') return;
    return attr.name + ':' + attr.value.slice(2,-2);
  }

  ko.punches.utils.addNodePreprocessor(function(node){
    if(node.nodeType !== 1)
      return null;

    var params = node.getAttribute('params');
    params = params ? [params] : [];

    [].forEach.call(node.attributes,function(attr){
      if(attr.name !== 'params'){
        var p = getAttributeValue(attr);
        if(p) params.push(p), node.removeAttribute(attr.name);
      }
    });
    if(params.length > 0) node.setAttribute('params',params.join(','));
  });

i have tested above code and it's working. what do you think ?

crissdev commented 9 years ago

I can't see how cusom attributes can be confused with data-bind attribute if the rule is applied only to registered components. I would agree on the solution proposed by @kaleb over another convention ((...)). I might be wrong so I'm open to criticism :smile:

aminroosta commented 9 years ago

what about this ?

<my-element data-bind="visible:some_condition" params="foo: bar "></my-element>

if we write something like the following

<my-element visible="{{some_condition}}" foo="{{bar}}"></my-element>

then how to differentiate between visible and foo attributes ?

crissdev commented 9 years ago

I can't say it's not tempting but having both data-bind and params attributes on the component element seems to complicate reading it. But this is just a matter or preference. Handling by default the attributes as params seems reasonable to me, while data-bind can remain as it is.

For example:

<my-element foo="{{bar}}" visible="{{condition}}" data-bind="attr.title: 'my tooltip'">
</my-element>

<!-- would be transformed to -->

<my-element params="foo: bar, visible: condition" data-bind="attr: {title: 'my tooltip'}">
</my-element>

So, all attributes go into params and data-bind is processed as it is right now.

aminroosta commented 9 years ago

So that way

<div visible="{{condition}}"></div>
<!-- would be transformed to -->
<div data-bind="visible: condition"></div>

<!-- and for custom elements -->
<my-element visible="{{condition}}"></my-element>
<!-- would be transformed to -->
<my-element parmas="visible:condition"></my-element>

I have no problem with that, but that doesn't sound about right. we are making an exception for the custom elements.I think we should keep the syntax consistent .
I agree with you that we should avoid creating new conventions like visible="((condition))".
So both solutions are somehow wrong !

gmhispagnol commented 7 years ago

Angular and Aurelia are using the attribute name itself, like:

<div visible.bind="condition"></div>

LayZeeDK commented 7 years ago

Angular does this:

<my-element [visible]="condition" [foo]="bar" baz="static123" [title]="tooltipProperty"></my-element>

I think that you should keep this talk on creating a web components-like syntax like <my-element foo="{{ bar }}"></my-element> and create another discussion for an extended JavaScript property binding syntax like <img title="{{ image.title }}" />.

These are really two different topics.

mbest commented 7 years ago

@LayZeeDK <img title="{{ image.title }}" /> is already supported.