2017-02-06 7 views
1

Dieser Teil meiner Form ist:Formwert in der Steuerung nicht festgelegt, bis Seite Fokus Aktualisierung

<form name="form.activityForm" class="form-horizontal" ng-submit="save(form.activityForm.$valid)" 
      enctype="multipart/form-data" novalidate> 
    <fieldset> 
     <div class="form-group" ng-if="!activity._id"> 
      <label for="gpxData" ng-class="{ 'disabled': gpxFileName }" class="btn btn-primary btn-file">Upload GPX 
       <input type="file" nv-file-select name="gpxData" id="gpxData" ng-model="gpxData" uploader="uploader" 
          onchange="angular.element(this).scope().setFileName()" hidden> 
      </label> 
      <span ng-if="gpxFileName" ng-bind="gpxFileName"></span> 
     </div> 

     <div class="form-group" show-errors> 
      <label class="control-label" for="name">Name</label> 
      <input name="name" type="text" ng-model="activity.name" id="name" class="form-control" 
         ng-disabled="!gpxFileName" required> 
      <div role="alert" class="alert alert-danger" ng-if="(activity.name === 'N/A') && (gpxFileName)"> 
       <p>This activity does not have a <strong>name</strong>. Please select one.</p> 
      </div> 
      <div ng-messages="form.activityForm.name.$error" role="alert"> 
       <p class="help-block error-text" ng-message="required">Activity name is required.</p> 
      </div> 
     </div> 

     ... 
    </fieldset> 
</form> 

setFileName()

$scope.setFileName =() => { 
    let fr = new FileReader(), 
     gpxFile = document.getElementById("gpxData").files[0], 
     filename = gpxFile.name; 

    fr.onload =() => { 
     let gpxDataXml = parseXmlFromString(fr.result); 

     setNameTypeDescription(gpxDataXml.documentElement); 
    }; 
    fr.readAsText(gpxFile); 
    $scope.gpxFileName = filename; 
}; 

setNameTypeDescription()

let setNameTypeDescription = (gpxDataXmlDocumentElement) => { 
    let activityType = getSingleTagData(gpxDataXmlDocumentElement, "type"); 

    $scope.activity.name = getSingleTagData(gpxDataXmlDocumentElement, "name"); 
    $scope.activity.description = getSingleTagData(gpxDataXmlDocumentElement, "descr"); 

    $scope.activityTypes.forEach((type) => { 
     if (type.name.toLowerCase() === activityType.toLowerCase()) { 
      $scope.activity.type = type; 
     } 
    }); 
}; 

Wenn ich log aus die Werte $scope.activity.name) nachdem sie in der Steuerung geändert wurden, bekomme ich die erwartete Ausgabe. Jedoch nicht die Werte (dh ng-model="activity.name") in der Vorlage aktualisieren, bis Fokus wieder auf der Seite (dh auf eine Schaltfläche)

EDIT:

hinzuzufügen, ich brauche ng-model wie ich verwende brauche 2-Wege-Bindung. Obwohl der Wert ursprünglich im Controller festgelegt wurde, kann der Benutzer auch den Wert in der Vorlage ändern, und beim Senden des Formulars wird dieser Wert in Mongo gespeichert.

Auch ng-bind arbeitet in diesem Szenario nicht.

+0

versuchen, ng-model-options doc finden Sie hier https://docs.angularjs.org/api/ng/directive/ngModelOptions – MMK

+0

Ich bin nicht sicher, welche Attribute mit 'ng-model-options' und ich einstellen die Dokumentation gelesen haben – wmash

+0

zu Versuchen '$ timeout' an die Steuerung und Änderung' $ scope.activity.name = getSingleTagData (gpxDataXmlDocumentElement, "name") einspritzt; 'auf' $ timeout (function() {$ scope.activity.name = getSingleTagData (gpxDataXmlDocumentElement, "name");}); ' –

Antwort

2

Ihr Problem ist, dass Sie die Werte sind, die die Aktualisierung der Ansicht gebunden sind, aber kantig „wissen“ nicht, dass sie Updates waren. Angular Aktualisierungen der Blick auf jeden Zyklus verdauen, die viele Male geschieht - Wenn der Benutzer interagiert mit der Ansicht oder nach jeder Änderung auf den Umfang, die Winkel der Lage ist, zu verfolgen.

In Ihrem Fall rufen Sie die setNameTypeDescription, nachdem die Dateiänderungen (Mit Hilfe der onchange Ereignis auf der Datei-Eingabe. Da onchange keine native Winkel Richtlinie ist, müssen Sie Winkel wissen lassen, dass sich etwas geändert wurde, manuell.

es funktionierte, wenn konzentrierte sich wieder auf die Seite, weil es einen Digest Zyklus ausgelöst, der die Ansicht aktualisiert, aber Sie können es von der Steuerung wie folgt tun:

$timeout(function() { 
    $scope.activity.name = getSingleTagData(gpxDataXmlDocumentElement, "name"); 

    // You can also put here other view related changes, you don't need a separate $timeout for every change 
}); 

natürlich - nicht zu injizieren $timeout an den Controller vergessen !

Beachten Sie, dass Sie auch den Code mit $scope.$apply(function() { ... }); wickeln kann, aber $timeout schon macht es für Sie, und ich ziehe $timeout, weil Sie nicht Fehler wie $ Digest bereits im Gange erhalten, wenn $ scope aufrufen. $ Apply() wie in this question erläutert.

0

Versuchen ng-bind anstelle von ng-Modell

+0

Das ist nur 1 Weg verbindlich. Ich brauche 2-Wege-Bindung – wmash

+0

Ich habe auch die 'ng-bind' Richtlinie zu verwenden versucht, und nicht * (unter Umständen auch auf Seite refocus) * – wmash

+0

den Wert im Controller ein, indem Sie die ID der Eingabe anstelle von $ scope –

Verwandte Themen