2016-04-17 4 views
0

Mein erstes KO-Projekt hat einen Editor Komponente, die eine Basisklasse für allgemeine Funktionen "anwendet" und eine untergeordnete Schaltflächenkomponente implementiert, um Schaltflächen mit Schaltflächen zum Speichern/Abbrechen/Zurücksetzen und zugehörige Ereignisbehandlung bereitzustellen.Knockout Sub-/Pub-Benachrichtigung zweimal empfangen

Die Komponente "Buttons" muss Click-Events behandeln und die Editor-Basisklasse informieren, die dann entscheidet, wie sie damit umgehen soll.

Ich wollte KO's Pub/Sub-Funktionalität verwenden, um die Kommunikation zu handhaben und versuchte zuerst das Knockout-Postbox-Plugin, aber erhielt eine doppelte Veröffentlichung, so habe ich es auf ein einfaches Pub/Sub-Setup reduziert, vergeblich .

Das Ereignis "Click" wird nur einmal ausgelöst und die Übertragung wird gestoppt, die Benachrichtigung wird jedoch zweimal empfangen.

Klar mache ich etwas falsch, aber ich ratlos bin, was es ist ...

Kann jemand sehen, warum der bekannte Alarm zweimal feuern würde?

App.js

var appViewModel = function() { 
    var self = this; 
    self.postbox = new ko.subscribable(); 
    return new appViewModel(); 
}) 

Buttons.html

<div class="nav btn-group editButtons"> 
    <button class="btn btn-default" data-bind="click:reset">Reset</button> 
    <button class="btn btn-warning" data-bind="click:cancel">Cancel</button> 
    <button class="btn btn-primary" data-bind="click:save">Save</button> 
</div> 

Buttons.js

define(['App/app','jquery', 'knockout', 'text!./editorButtons.html', 'strings'], function (app,$, ko, htmlString) { 

    function EditorButtons(params) { 
    var self = this; 
    var clickTopic = "{0}EditorButtonClicked".format(params.namespace); 

    // **** THIS FIRES ONCE ***** 
    self.save = function (me, e) { 

     e.preventDefault(); 
     e.stopImmediatePropagation(); 
     app.postbox.notifySubscribers("save", clickTopic); 
     return false; 
    } 
    } 
    return { viewModel: EditorButtons, template: htmlString }; 
}); 

EditorBaseClass

define(['knockout', 'jquery', 'App/app', 'strings'], function (ko, $, app) { 

    EditorBaseClass = function (parent, item, mode, namespace) { 
     var self = this; 
     self.mode = ko.observable(mode); 
     var clickTopic = "{0}EditorButtonClicked".format(namespace); 


     // **** This Alert fires Twice *****/ 
     app.postbox.subscribe(function (clickType) { 

      alert(clickType); 

     }, self, clickTopic); 
    } 
}); 

Eltern Editor

define(['jquery', 'knockout', 'App/app', 'text!./myEditor.html', 'models/EditorBaseClass'], function ($, ko, app, htmlString, editor) { 

    function MyEditor(params) { 
     var self = this; 
     EditorBaseClass.apply(self, [self, params.item, params.mode, "myNamespace"]); 
    } 
    return { viewModel: MyEditor, template: htmlString }; 
}); 

Vielen Dank für alles, was Sie erkennen könnte - ich kann JQuery Ereignisse zurückgehen, aber ich würde dies gerne in meinem Toolkit haben.

+0

Können Sie das mit einer Geige neu erstellen? – janmvtrinidad

+0

Sie können dieses [plugin] (https://github.com/rniemeyer/knockout-postbox) für Ihre Anwendung pub/sub verwenden. – janmvtrinidad

Antwort

1

Aus dem, was ich aus Ihrem Beispiel verstehe, scheint es, dass Sie einen bestimmten Kanal veröffentlichen und abonnieren möchten (z. B. "Speichern"). Davon abgesehen, würde ich folgendes ändern:

self.save = function (me, e) { 
    e.preventDefault(); 
    e.stopImmediatePropagation(); 
    // you should use ko.postbox to publish to a channel 
    ko.postbox.publish("save", clickTopic); 
    return false; 
} 

und

// also also use ko.postbox to subscribe to a channel 
ko.postbox.subscribe("save", function (clickType) { 
    alert(clickType); 
}); 

Ein vollständiges Beispiel here zu sehen ist. Ich habe versucht, Ihren ursprünglichen Code zu behalten, damit Sie ihn leichter abholen können.

P.S. Ich denke, es ist besser für Sie, die knockout-postbox documentation genauer zu betrachten, da es scheint, dass Sie die Grundlagen vermissen.

+0

danke sehr für die arbeit geige, es funktioniert mit dem postbox plugin. Nur eine Anmerkung - mein Code sieht nicht wie Postbox-Plugin-Code aus, weil es nicht ist. Die Variable 'Postbox' ist ein einfaches Ko-Zeichen und der Code ist mein Versuch, KOs native Pub/Sub-Einrichtungen zu implementieren/ohne/das Plugin wie hier beschrieben: http://www.knockmeout.net/2012/05/using- ko-native-pubsub.html - das sagte alles, ich habe es funktioniert, und schätze den Zeiger :-) – Serexx