KnockoutJS: Hinzufügen von Observable-Eigenschaften und -Funktionen zu Objekten in einem von ObservableArray generierten Mapping

StackOverflow https://stackoverflow.com/questions/8401799

Frage

Ich bin neu in KnockoutJS und versuche nicht, den generierten Objekten zusätzliche Eigenschaften und Methoden hinzuzufügen im ko.observableArray(), wie er vom mapping-Plugin erstellt wurde.


Hier bin ich:

War es hilfreich?

Lösung

Es gibt verschiedene Optionen, die Sie in Betracht ziehen könnten.

-Eine ist die Verwendung des create callback , um zu steuern, wie Ihr "Benutzer" "Objekte werden erstellt. Sie können die Observablen entweder selbst definieren und zusätzliche Funktionen hinzufügen oder das Mapping-Plugin für das einzelne Benutzerobjekt aufrufen und dann zusätzliche Funktionen hinzufügen.

Wäre ungefähr so: http://jsfiddle.net/rniemeyer/fkVaK/

- Andernfalls können Sie die Funktion "Umschalten" in Ihr viewModel einfügen und dann das Objekt "Benutzer" an dieses übergeben.

Eine gute Möglichkeit mit 1.3 ist die Verwendung von ko.dataFor zusammen mit der Live- / Delegate- / On-Event-Delegierungsfunktion von jQuery. Wäre wie folgt: http://jsfiddle.net/rniemeyer/FkjNr/

//unobtrusive event handler
$(".toggle").live("click", function() {
    var user = ko.dataFor(this);
    if (user) {
       viewModel.toggleIsActive(user);
    }
});

Wenn Sie die Ereignisdelegierung nicht verwenden möchten, können Sie das Element direkt mit einer anonymen Funktion wie der folgenden übergeben: > http://jsfiddle.net/rniemeyer/GpQtN/

BEARBEITEN: Ab Version 2.0 werden die aktuellen Daten automatisch an den Handler übergeben, wenn Klick- / Ereignisbindungen verwendet werden. Sie können also einfach Folgendes tun:

<a href="#" data-bind="click: $root.toggleIsActive"><span data-bind="text: IsActive"></span></a>

Andere Tipps

Dies ist, was ich mit Ihren und Ryans Antworten gefunden habe ... scheint zu funktionieren.Bitte hinterlassen Sie Feedback, da ich neu bei Knockout bin und selbst neugierig bin, ob dies ein guter Ansatz ist.

JS:
$(function() {
    $.get("users/getUsers", function(r){
        var vm = ko.mapping.fromJS(r, {
            users: {
                create: function(user){
                    var methods = {
                        toggleIsActive: function(u){u.IsActive(!u.IsActive());},
                        foo: function(u){console.log(u);},
                        bar: function(u){/*whatever*/},   
                    }
                    return $.extend(ko.mapping.fromJS(user.data), methods);
                }
            }
        });
        ko.applyBindings(vm);
    }, 'json');
});

DOM:
<!-- ko foreach: users -->
   <a href="#" data-bind="click: toggleIsActive"><span data-bind="text: IsActive"></span></a>
<!-- /ko -->

Ich habe einen Weg gefunden, dies zu tun, aber es bedeutet, die generierten Objekte im Array zu durchlaufen, sobald sie erstellt wurden. Ich würde es vorziehen, das gleiche Ergebnis ohne die zusätzliche Schleife zu erzielen.

BEARBEITEN: Wie RP Niemeyer in seiner Antwort vorschlägt! ; o)

Eine Möglichkeit, einem vorhandenen Objekt Eigenschaften hinzuzufügen, ist die Verwendung von jQuery verlängern () um die Objekte zu kombinieren.

Deklarieren Sie zunächst die zusätzlichen Eigenschaften und Funktionen in einem neuen Objekt:

var userModel = {
    toggleIsActive: function() {
        console.log('toggleIsActive called: before: ' + this.IsActive());
        this.IsActive(!this.IsActive());
        // todo: save!
        console.log('toggleIsActive called: after: ' + this.IsActive());
    }
}

Führen Sie dann nach dem Aufruf des ko.mapping.fromJS() , jedoch vor dem Aufruf des ko.applyBindings() eine Schleife durch die Objekte im generierten Array und erweitern Sie sie:

viewModel.users = ko.mapping.fromJSON(/* get JSON */);

for (var i = 0; i < viewModel.users().length; i++) {
    $.extend(viewModel.users()[i], userModel);
}

ko.applyBindings(viewModel);

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top