2015-02-13 16 views
8

Ich habe eine Direktive Rendering-Eingaben basierend auf einer Konfiguration vom Server gesendet. Bis auf den 'Select'-Eingang funktioniert alles gut. Egal was ich versuche, das ng-Modell wird nicht aktualisiert. Ich habe meinen Code viel zu isolieren, um das Problem getrimmt:ngModel nicht aktualisieren in auswählen

Javascript:

var myApp = angular.module('example', []); 

    myApp.factory('DynamicData', [function() { 
     return { 
      data: { 
       backup_frequency: 604800 
      } 
     }; 

    }]) 
    .directive('dynamicInput', 
     ['$compile', 'DynamicData', function($compile, DynamicData) { 

      /** 
      * Render the input 
      */ 
      var render = function render() { 
       var input = angular.element('<select class="form-control" ng-model="inner.backup_frequency" ng-options="option.value as option.title for option in options"></select>'); 
       return input; 
      }; 

      var getInput = function() 
      { 
       var input = render(); 
       return input ? input[0].outerHTML : ''; 
      }; 

      var getTemplate = function(){ 

       var template = '<div class="form-group">' + 
           'Select input ' + 
           '<div class="col-md-7">' + getInput() + '</div>' + 
          '</div>'; 
       return template; 
      }; 

      return { 
       restrict : 'E', 
       scope: { 
        content:'=content', 
       }, 

       link : function(scope, element, attrs) { 
        var template = getTemplate(); 

        scope.options = [ 
         {title: "Daily", value: 86400}, 
         {title: "Weekly", value: 604800}, 
         {title: "Monthly", value: 2678400}, 
         ]; 
        scope.inner = DynamicData.data; 
        console.info('inner data', scope.inner); 

        element.html(template); 
        element.replaceWith($compile(element.contents())(scope)); 


       } 
      }; 
     }]) 
     .controller('FormCtrl', ['DynamicData', '$scope', function (DynamicData, $scope){ 
     $scope.app = {}; 

     $scope.save = function save() { 
      $scope.value = DynamicData.data.backup_frequency; 
      console.info('DynamicData', DynamicData.data); 
     }; 
     }]); 

HTML:

<head> 
    <script data-require="[email protected]" data-semver="1.3.8" src="https://code.angularjs.org/1.3.8/angular.js"></script> 
    <link href="style.css" rel="stylesheet" /> 
    <script src="script.js"></script> 
    </head> 

    <body> 
    <h1>Dynamic Input :</h1> 
    <div data-ng-controller="FormCtrl"> 
     <dynamic-input class="form-group" content="app"></dynamic-input> 
     <span data-ng-bind="value"></span><br/> 
     <button class="btn btn-primary" ng-click="save()">Save</button> 
    </div> 
    </body> 

</html> 

Eine Arbeits Plunker steht zur Verfügung: http://plnkr.co/edit/mNBTJzZXjX6mLyPz6NCI?p=preview

Sie tun habe irgendwelche Ideen, warum das ng-Modell in der Auswahl nicht aktualisiert wird?

EDIT: Was ich erreichen möchte, ist die Aktualisierung der Variable "inner.backup_frequency" (der Verweis auf mein Datenobjekt von meiner Fabrik DynamicData zurückgegeben). Wie Sie im Plocker sehen können, wird die im ng-Modell enthaltene Variable nicht aktualisiert, wenn ich die Option in der Auswahl ändere.

Vielen Dank für Ihre Zeit.

+0

wollen Sie dass'
'jedes Mal anders zu sein, die ich klicken. oder den Wert in den Optionen, um gültig zu sein .. bitte erklären Sie –

+0

Hallo, haben Sie versucht, das Ereignis on change auf der Auswahl und in Javascript die $ scope.varailable und als $ scope. $ apply() nur um zu sehen wenn es etwas damit zu tun hat, dass das Element außerhalb der $ Digest-Schleife liegt? – Andreas

+1

Siehe http://stackoverflow.com/a/22890796/446030 bezüglich der Reihenfolge der Kompilierung und Platzierung innerhalb des Doms. – JcT

Antwort

3

Ich habe es behoben. Was Sie tun mussten, war, den Inhalt des Elements nicht durch den kompilierten Inhalt zu ersetzen, sondern ihn durch den reinen HTML-Code zu ersetzen und ihn dann zu kompilieren.

element.html(template); 
$compile(element.contents())(scope); 

Working Plunker.

EDIT: Ich habe den Code bearbeitet, ohne die Richtlinie zu arbeiten:

Plunker without directive.

EDIT 2: Auch eine Version, wo es mit der Richtlinie arbeitet, aber ohne die Kompilierung:

Plunker.

+0

Hallo, danke für deine Antwort, es funktioniert.Allerdings würde ich wirklich gerne mein DOM aufhellen und das 'dynamic-input' HTML-Tag entfernen. Irgendwelche Ideen ? –

+0

@AlexandreNucera Ja, es sieht so aus, als ob die Direktive nur hartcodiertes HTML erzeugt, warum nicht einfach das benutzen und das Kompilieren verlieren usw.? –

+0

Ok, das scheint der Trick zu sein: var e = $ compile (template) (scope); element.replaceWith (e); (Ich werde Ihnen morgen das Kopfgeld geben, ich muss 21h warten) –

13

Ich hatte ein ähnliches Problem und finde, wenn Sie ng-Modell direkt an eine Scope-Variable wie unten binden, wird die Auswahl der Scope-Variablen irgendwie nicht aktualisiert werden.

<select ng-model="selection" ng-options="option for option in options"> 

stattdessen eine Ansicht Modell in Ihrem Umfang und binden ng-Modell zu einem Sichtfeld Modell definiert die Ansicht Modellfeld aktualisiert.

<select ng-model="viewmodel.selection" ng-options="option for option in options"> 

In Ihrem Controller, sollten Sie dies tun:

app.controller('SomeCtrl', ['$scope' 
    function($scope) 
    { 
     $scope.viewmodel = {}; 
    }); 
+2

Die Take-Aways, die eine große Hilfe für mich waren: • das Modell muss eine * Eigenschaft * auf einer Scope-Variable sein - keine Scope-Variable • es ist am besten zu * nicht * Zuweisen der Eigenschaft der Scope-Variablen in JS - referenzieren Sie sie einfach im HTML und eckig erstellt sie und aktualisiert sie – rushkeldon

+0

Denken Sie nur daran: "Der Scope ist nicht das Modell, der Scope bezieht sich ** auf das Modell" und "Immer wenn Sie habe ng-model ** da muss irgendwo ein dot ** drin sein. Wenn du keinen Punkt hast, machst du es falsch. "[Mehr] (http://jimhoskins.com/2012/12/14/nested-scopes-in-angularjs.html) – dr3w

Verwandte Themen