2014-09-05 9 views
6

Kann ein Knockout custom element das params-Attribut an ein Objekt wie ein Component binding gebunden haben?Kann ein benutzerdefiniertes Element ein Objekt für die Params wie die Komponente Binding übergeben werden?

Zum Beispiel habe ich die folgende Komponente definiert:

ko.components.register('user-widget', { 
    template: '<p><span data-bind = "text:fullName" ></span></p>', 
    viewModel: function (params) { 
     this.fullName = params.firstName + ' ' + params.lastName; 
    } 
}); 

und die folgenden VM:

function VM() { 
    this.user = { 
     firstName: 'Joe', 
     lastName: 'Baker' 
    }; 
} 

Wenn eine Komponente mit Bindung ich die Benutzereigenschaft der VM übergeben kann direkt an den params Attribut wie folgt:

<div data-bind='component:{name:"user-widget", params:user}'></div> 

Wenn ich jedoch ein benutzerdefiniertes Element verwende, muss ich t auspacken er Benutzereigenschaft wie folgt:

<user-widget params="firstName:user.firstName, lastName:user.lastName"></user-widget> 

Ich habe versucht, ein eigenes Element unter Verwendung mit einer Bindungskomponente in etwa so:

<user-widget data-bind='component:{params:user}'></user-widget> 

die in den folgenden Fehler führt:

Cannot use the "component" binding on a custom element matching a component

JsFiddle

Antwort

4

Nun, Sie müssen Ihre Komponente ändern, um einen Benutzerparameter anstelle von jedem zu akzeptieren separater Parameter

<user-widgetx params='user: user'></user-widgetx> 
ko.components.register('user-widgetx', { 
    template: '<p><span data-bind = "text:fullName" ></span></p>', 
    viewModel: function (params) { 
     this.fullName = params.user.firstName + ' ' + params.user.lastName; 
    } 
}); 

fiddle


erforschte ich die Idee der Bindungs ​​Anbieter von Zwicken in den Parsing-Code einzuhaken. Ich konnte Dinge zum Laufen bringen. Aber ich muss Sie warnen, das ist auf jeden Fall ein Hack. Dies wurde mit Knockout v3.2 getestet und ich kann nicht garantieren, dass dies immer funktioniert. Zumindest solange, bis sie die Kernfunktionalität von Knockout auf andere Weise erweitern.

Mit Blick auf die Quelle, habe ich festgestellt, dass die params Parsing-Code knownout eingebauten Bindung Parser verwendet. Wenn wir also irgendwie in den Parser einhaken können, können wir einstellen, wie die Binding-Strings interpretiert werden, um das zu erreichen, was wir wollen.

Ziel ist es, einen neuen Bindungstyp zu erstellen, damit der analysierte Ausdruck als das eigentliche Bindungsobjekt behandelt wird. Dies könnte auch außerhalb der Komponentenparameter weiter verwendet werden. Auf diese Weise können wir dies tun in unserer Bindungen/params:

<user-widget params='${user}'></user-widget> 

Jetzt alles im ${ } kann als die Bindung/params Objekt behandelt werden.

(function() { 
    var originalParseBindingsString = ko.bindingProvider.prototype.parseBindingsString, 
     re = /^\$\{(.+)\}$/; 

    function extractBindableObject(objExpr, bindingContext, node, options) { 
     var objBindingString = '_object: ' + objExpr, 
      objGetter = originalParseBindingsString.call(this, objBindingString, bindingContext, node, options), 
      obj = objGetter['_object'](); 
     return objectMap(obj, function (value) { 
      return function() { return value; }; 
     }); 
    } 

    function objectMap(obj, mapper) { 
     if (!obj) return obj; 
     var result = {}; 
     for (var prop in obj) { 
      if (obj.hasOwnProperty(prop)) 
       result[prop] = mapper(obj[prop], prop, obj); 
     } 
     return result; 
    } 

    ko.bindingProvider.prototype.parseBindingsString = function (bindingsString, bindingContext, node, options) { 
     var m = bindingsString.match(re); 
     if (m) { 
      return extractBindableObject.call(this, m[1], bindingContext, node, options); 
     } 
     return originalParseBindingsString.apply(this, arguments); 
    }; 
}()); 

fiddle

+0

Das ist nicht genau das, was ich suche. Ich weiß, dass ich einen einzelnen Parameter als ein Objekt übergeben kann, wie Sie es gezeigt haben. Ich möchte jedoch das Attribut params an ein einzelnes Objekt binden, wie dies bei der Komponentenbindung der Fall ist. –

+0

Ich fürchte, was Sie suchen ist derzeit nicht möglich.Wenn Sie die Quelle betrachten, suchen benutzerdefinierte Komponenten gezielt nach einem Attribut "params". Es verwendet jedoch den Bindungsanbieter, um die Bindungen zu analysieren. Wenn Sie möchten, können Sie ein neues Bindungsschema erstellen, sodass Sie das übergebene Objekt stattdessen als analysierte Bindungen verwenden können. –

+0

Tut mir leid, dass es so aussieht, als ob der bindende Provider nicht eingebunden werden kann. in diesem Fall –

Verwandte Themen