2013-03-11 7 views
5

Ich schrieb eine Direktive für Redactor (ein Wysiwyg-Editor). Es funktioniert nach etwas Hacking, aber ich würde gerne den richtigen Weg finden. Die größte Herausforderung für mich ist die bidirektionale Bindung zwischen dem ng-Modell und dem Redactor jquery Plugin. Ich höre Schlüsselwort und Befehlsereignis vom Wysiwyg-Editor und aktualisiere das Modell. Ich beobachte auch den Modellwechsel von außerhalb des Redactor-Editors, damit ich den Redactor-Editor entsprechend aktualisieren kann. Der heikle Teil ist: Wie ignoriere ich die ng-Modelländerung, die vom Reaktoreditor auferlegt wird (von der ersten Hälfte der Bindung)?Angular Directive - Wie bidirektionale Bindung mit ng-Modell

Im folgenden Code merkt es sich den letzten Wert, den der redactor-Editor für das Modell aktualisiert, und ignoriert die Modelländerung, wenn der neue Wert des Modells dem letzten Wert entspricht. Ich bin mir wirklich nicht sicher, ob dies der richtige Weg ist. Es scheint mir, dass dies ein häufiges Problem bei der bidirektionalen Bindung in Angular ist und dass es einen Weg geben muss. Vielen Dank!

<textarea ui-redactor='{minHeight: 500}' ng-model='content'></textarea> 

directive.coffee (sorry für das Coffeescript)

angular.module("ui.directives").directive "uiRedactor", -> 

    require: "ngModel" 
    link: (scope, elm, attrs, ngModel) -> 
    redactor = null 
    updatedVal = null 

    updateModel = -> 
     ngModel.$setViewValue updatedVal = elm.val() 
     scope.$apply() 

    options = 
     execCommandCallback: updateModel 
     keydownCallback: updateModel 
     keyupCallback: updateModel 

    optionsInAttr = if attrs.uiRedactor then scope.$eval(attrs.uiRedactor) else {} 

    angular.extend options, optionsInAttr 

    setTimeout -> 
     redactor = elm.redactor options 

    #watch external model change 
    scope.$watch attrs.ngModel, (newVal) -> 
     if redactor? and updatedVal isnt newVal 
     redactor.setCode(ngModel.$viewValue or '') 
     updatedVal = newVal 
+3

Statt $ watch() haben Sie ngModel umzusetzen versucht. $ Render()? Es scheint, dass $ render() nur aufgerufen wird, wenn etwas in Angular das Modell ändert. In diesem [fiddle] (http://jsfiddle.net/mrajcok/SKgVS/) wird $ render() nur aufgerufen, wenn ich auf den Link klicke (der das Modell programmatisch ändert). (Da ich keine Redactor-Lizenz habe, kann ich das nicht testen.) –

+0

Mark, das hat für mich funktioniert. Vielen Dank! – KailuoWang

+0

Toll, froh, dass es funktioniert hat, und danke, dass Sie uns wissen lassen. –

Antwort

0

Mark Rajcok gab die Lösung (Danke!) Der Trick ist ngModel zu verwenden. $ Render() statt $ watch() .

Verwendung

ngModel.$render = -> 
    redactor?.setCode(ngModel.$viewValue or '') 

statt

scope.$watch attrs.ngModel, (newVal) -> 
    if redactor? and updatedVal isnt newVal 
    redactor.setCode(ngModel.$viewValue or '') 
    updatedVal = newVal 
+0

Das in der Vorlage definierte ng-Modell wird nicht mit dieser Anweisung aktualisiert? Hast du eine Idee warum? –

Verwandte Themen