2014-02-26 10 views
5

Ich habe eine wirklich einfache CRUD-App zum Verwalten von Musikalben. Nur zwei Felder werden verfolgt, Titel und Künstler.Angular - Verwenden des gleichen Formulars zum Erstellen und Aktualisieren

In this example zeigt das Dropdown eine Liste von Alben, und wenn ich das Formular ausfülle und auf Speichern klicke, wird es zur Liste hinzugefügt.

In der second example wird durch Auswahl eines Albums das Formular ausgefüllt, damit es bearbeitet und aktualisiert werden kann.

Meine Frage ist, gibt es eine Möglichkeit, beide Funktionen in der gleichen Form zu bekommen? Sicher könnte ich zwei identische Formulare erstellen und sie etwas andere Dinge tun lassen, aber da sie mit den gleichen Daten arbeiten, wäre es nett, wenn ein current_album ausgewählt wird, wird es aktualisiert, und wenn "New album..." ausgewählt ist, erstellt es.

Der Haupthindernisblock scheint Wert gegen ng-Modell zu sein. Ich kann den Wert so einstellen, dass er ausgefüllt wird, wenn ich ein Objekt aus der <select> ODER eine ng-model="newAlbum" setze, aber nicht beides nach meinem Wissen.

Antwort

5

Sie sollten das Attribut value nicht mit ng-model verwenden. Das ist eine sehr schlechte Übung.

Was ich vorschlagen würde ist, ng-change auf Ihrer Liste zu verwenden und ein geklontes Objekt mit dem Bearbeitungswert zu behalten.

$scope.onChange = function() { 
    if ($scope.currentAlbum) { 
    $scope.editing.title = $scope.currentAlbum.title; 
    $scope.editing.artist = $scope.currentAlbum.artist; 
    } else { 
    $scope.editing = {}; 
    } 
}; 

Das alles, was Sie tun müssen, wenn Spar Kontrolle ist, ist es ein neues Objekt oder nicht:

$scope.addOrSaveAlbum = function() { 
    if ($scope.currentAlbum) { 
    $scope.currentAlbum.title = $scope.editing.title; 
    $scope.currentAlbum.artist = $scope.editing.artist; 
    } else { 
    $scope.albums.push({ title: $scope.editing.title, artist: $scope.editing.artist }); 
    } 

    $scope.editing = {}; 
}; 

Siehe http://jsfiddle.net/4Zeuk/12/

(danke an wawy ng-change darauf hinzuweisen, statt $scope.$watch)

+0

+1 für eine bessere Lösung! – dfsq

1

Sie können tatsächlich beide Funktionen ohne die Notwendigkeit von zwei verschiedenen Formen, aber Sie können nicht das gleiche Ziel verwenden t im Bereich im ng-Modell für Auswahl- und Formularfelder.

Sie können jedoch zwei verschiedene Objekte im Bereich haben, von denen einer den Wert des ausgewählten Objekts enthält und der andere entweder eine neue Instanz eines Albums oder eine Kopie des ausgewählten Objekts enthält. Wenn Sie dann auf die Schaltfläche Speichern/Aktualisieren klicken, können Sie basierend auf der ID des Objekts im Formular entscheiden, ob Sie die Album-Sammlung speichern oder ändern möchten. Hier

ist eine Möglichkeit, zu tun, was ich gerade erklärt:

<div ng-app="albumShelf"> 
<div ng-controller="MainCtrl"> 
    <div style="float:left;"> 
    <select ng-options="b.title for b in albums" ng-model="current_album" ng-change=updateForm()> 
     <option value="">Choose album...</option> 
    </select> 
    </div> 

    <div style="float:left;"> 
     <form> 
     <input type="text" ng-model="newAlbum.title"> 
     <br> 
     <input type="text" ng-model="newAlbum.artist"> 
     <br> 
     <input type="submit" value="{{ current_album ? 'Update' : 'Save' }}" ng-click="modifyAlbumCollection()"> 
     </form> 
    </div> 
</div> 

var albumShelf = angular.module('albumShelf', [/*'ngResource'*/]) 
.controller('MainCtrl', ['$scope', function($scope/*, albumFactory*/) { 
    //$scope.albums = albumFactory.query(); 

    $scope.albums = [ 
     { id: 1, title: 'Disorganized Fun', artist: 'Ronald Jenkees' }, 
     { id: 2, title: 'Secondhand Rapture', artist: 'MS MR' } 
    ]; 

    $scope.modifyAlbumCollection = function() { 
     if ($scope.newAlbum.id !== null) { 
      //We are modifying an existing album 
      var i, found = false; 
      for (i = 0; i<$scope.albums.length && !found; i++) { 
       if ($scope.albums[i].id === $scope.newAlbum.id) { 
        $scope.albums[i] = angular.copy($scope.newAlbum); 
        found = true; 
       } 
      } 
     } else { 
      //We are adding a new album to the collection 
      $scope.newAlbum.id = $scope.albums.length; 
      $scope.albums.push(angular.copy($scope.newAlbum)); 
      $scope.newAlbum = { id: null, title: '', artist: '' }; 
     } 
    }; 

    $scope.updateForm = function() { 
     if ($scope.current_album) { 
      //Copy the information from the selected album into the form. 
      $scope.newAlbum = angular.copy($scope.current_album); 
     } else { 
      //Clear previous album info. 
      $scope.newAlbum = { id: null, title: '', artist: '' }; 
     } 
    }; 
}]) 
//.factory('albumFactory', function($resource) { 
// return $resource('/albums/:albumId.json', { albumId: '@id' } 
// ); 
//}); 

Hier ist die jsfiddle

Meiner Meinung nach ist es klar, wenn Sie einen ng verwenden - Ändern Sie in der Auswahl statt einer $ Uhr auf dem ng-Modell Wert. Was Sie wollen, ist das Formular zu aktualisieren, wenn ein neuer Wert aus dem Dropdown ausgewählt wird, anstatt auf Änderungen am Objekt im Bereich $ zu achten.

Verwandte Themen