1

Ich versuche, Daten zwischen Controllern mit einem Dienst zu übergeben, aber ich habe Probleme, da es nichts zurückgibt.Wie Daten zwischen Controllern mit einem Dienst in Angular übergeben werden

Hier ist mein Service:

app.service('myService', function() { 
    var savedData = ""; 
    return { 
     get: function() { 
      //You could also return specific attribute of the form data instead 
      //of the entire data 
      return savedData; 
     }, 
     set: function (data) { 
      //You could also set specific attribute of the form data instead 
      this.savedData = data; 
     } 
    }; 

}); 

Hier ist der Controller die Daten unter Verwendung einer Funktion namens goToAccount() zu speichern:

app.controller("chatController", ["$scope", "$firebaseArray", "Auth", "$window", "$state", "myService", 
    function($scope, $firebaseArray, Auth, $window, $state, myService) { 
     $scope.message = 'ChatRoom'; 
     $scope.auth = Auth; 
     $scope.auth.$onAuthStateChanged(function(firebaseUser) { 
     $scope.firebaseUser = firebaseUser; 
     console.log("Name: "+firebaseUser.displayName + "," + firebaseUser.email); 
     firebaseUser.providerData.forEach(function (profile) { 
      console.log("Sign-in provider: "+profile.providerId); 
      console.log(" Provider-specific UID: "+profile.uid); 
      console.log(" Provider Name: "+profile.displayName); 
      console.log(" Provider Email: "+profile.email); 
      console.log(" Provider Photo URL: "+profile.photoURL); 
      user = profile; 
      }); 

     }); 

     var ref = firebase.database().ref().child("messages"); 
     // create a synchronized array 
     $scope.messages = $firebaseArray(ref); 
     // add new items to the array 
     // the message is automatically added to our Firebase database! 
     $scope.addMessage = function() { 
      $scope.messages.$add({ 
       user: user.displayName, 
       email: user.email, 
       text: $scope.newMessageText 
      }); 
     }; 
     $scope.goToAccount = function(email){ 
      myService.set(email); 
      console.log(" Email: "+email); 
      $window.location.href = "/account.html" 
     } 
    } 
]); 

Und hier ist der Controller, der die Daten erhält. myService.get() gibt leeren Raum:

app.controller("accountCtrl", ["$scope", "Auth", "$window", "$state",  "$stateParams", "myService", 
    function($scope, Auth, $window, $state, $stateParams, myService) { 
     console.log(myService.get()); 
     $scope.message = 'Account Page for id' + myService.get(); 
    } 
]); 

Die Funktion goToAccount in html mit einem ng-Klick ausgelöst wird:

<a ng-click="goToAccount(message.email)"> 

Was mache ich falsch? Gibt es eine einfachere Möglichkeit, Daten zwischen Controllern zu übertragen? Danke im Voraus.

+2

Sie sind se tting 'this.savedData', was der Kontext Ihres Dienstes ist, mit anderen Worten, das Festlegen einer Eigenschaft Ihres Dienstes. Sie geben jedoch 'savedData' zurück, das nur eine normale Variable ist, die nicht zu Ihrem Service gehört. Entweder benutze 'this' sowohl für get und set oder lasse es für beide weg. Nicht mischen und anpassen. Sie sehen zwei verschiedene 'savedData's, wenn das Sinn macht. – ste2425

+0

Wenn ich this.savedData zurückgebe, gibt es undefined zurück? –

+0

'this.savedData = data' Dies bezieht sich auf den Kontext, in dem Sie den Dienst aufrufen. Verwenden Sie einfach 'savedData = data' – Purushoth

Antwort

0

Ihr Service haben einen Tippfehler

app.service('myService', function() { 
    var savedData = ''; 
    return { 
     get: function() { 
      //You could also return specific attribute of the form data instead 
      //of the entire data 
      return savedData; 
     }, 
     set: function (data) { 
      //You could also set specific attribute of the form data instead 
      savedData = data; 
     } 
    }; 

}); 

Sie Wert in this.savedData Einstellung, aber sie erklärt es als var und Sie SavedData zurückkehren, das ist "".

+1

Ich denke, dass Sie mit dem Kontext von Dienstleistungen vermischt werden. Dies wirft derzeit eine nicht definierte Ausnahme auf 'savedData'. [siehe] (https://jsfiddle.net/n9cg1emm/1/). Der Kontext Ihres '.service' ist anders als der Kontext des zurückgegebenen Objekts. Nur FYI es ist nicht immer besser, eine Fabrik zu benutzen, sie sind zwei verschiedene Dinge für zwei verschiedene Anwendungsfälle. Services sind Singletons, deren "Instanz" in Ihrer App geteilt wird. Fabriken sind nicht. – ste2425

+0

Können Sie erklären, warum die Geige mit Ihrem Service nicht funktioniert? Implementiere ich es falsch? – ste2425

+1

Ok hab es, siehe jetzt – Rakeschand

0

Wenn Sie Service-Dienste verwenden, gibt es immer nur Array zurück.

app.service('myService', function() { 
    var savedData = []; 

     this.getsavedData = function() { 
      //You could also return specific attribute of the form data instead 
      //of the entire data 
      return savedData; 
     } 
     this.setsavedData = function (data) { 
      //You could also set specific attribute of the form data instead 
      savedData = data; 
     } 


}); 

kennen und erfahren Sie mehr über Dienstleistungen dieses

In Ihrem chatController youtube video aussehen

dies tun, es zu überprüfen funktioniert oder nicht, wie die

myService.setsavedData("welcome");

innen Ihre accountCtrl

hier versuchen, den Wert Willkommen in Alarm

alert(myService.getsavedData());

+0

Es gibt dann ein leeres Array zurück. –

+0

Nein, Sie sehen in der ** Funktion (Daten) ** übergeben Sie Parameter wie diese 'myService.setsavedData (" Hallo ")' in einem Ctrl und versuchen, 'myService.getsavedData()' in einer anderen Strg-es funktioniert –

+0

in Ihrem setsaveData-Update meine Antwort bitte sehen Sie –

1

Also Ihr laufen in eine Scoping vs Kontext Ausgabe zurückzukehren. versuchen Ill

der Setter

set: function(data) { 
    this.savedData = data; 
}, 

betrachtet Ihre Dienste Kontext oder dem Dienst es selbst für die Eigenschaft savedData zu erklären. Wenn Sie innerhalb Ihrer Servicemethoden this verwenden, wird diese Eigenschaft für Ihren Dienst selbst verfügbar gemacht. Sie können also in Ihrem Controller mit myService.savedData darauf zugreifen oder es sogar dort einstellen.

Der Getter:

get: function() { 
    return savedData; 
    } 

verweist nur eine normale Variable, nicht ganz sicher aus der Spitze von meinem Kopf, wenn ihre Verschlüsse oder lexikalischer Scoping (Neigung zu lexcial), der diese Arbeit macht. Irgendeine Art und Weise JavaScript wird zuerst in der set Methode für savedData aussehen, wenn es nicht finden kann, wird es seinen Weg zurück zu der Service-Deklaration arbeiten, wo Sie anfangs var savedData = ""; setzen und stattdessen diese Variable verwenden.

So, wie Sie sehen können, verwendet Ihr Dienst zwei verschiedene savedData für jede Methode.

Sie sollten entweder this für beide verwenden, wodurch die zugrunde liegende Dateneigenschaft Ihres Service verfügbar gemacht wird. Wenn das akzeptabel ist, können Sie auch die Getter und Setter verlieren und direkt auf die Eigenschaft zugreifen.

example

Oder die this auslassen und savedData privat zu Ihrem Dienst haben und es nur in Ihrem Service zugänglich sind.

example


EDIT

Dies ist für das zugrunde liegende Problem mit Ihrem Service, aber ich denke, @MMhunter mit seinem Kommentar auf etwas sein kann. Sie sagen, wenn Sie die Dienste korrekt implementieren, funktioniert es immer noch nicht. Nach der Einstellung des Dienstwerts wird jedoch auf eine andere Seite umgeleitet. Wenn Sie den Status Ihrer App auf dieser Seite nicht aktualisieren, wird Ihre eckige App auf der neuen Seite neu gestartet und alle Daten im Service werden gelöscht. Einzelseiten-Apps, die auf diese Weise funktionieren, laden nicht die gesamte Seite neu. Sie verwenden Partials und den URL-Hash, um einen neuen Partial-Code zu laden. Das bedeutet, dass die gesamte Seite nicht neu geladen wird. Es gibt eine Alternative dazu, dass Ihre App den Status zwischen dem Laden der Seite und dem Verwenden von local/sessionStorage beibehält. Ich kenne das Design des Rests Ihrer App nicht, daher ist es möglicherweise nicht geeignet.

2

Es gibt mehrere Möglichkeiten, Daten zwischen Controller oder Komponenten zu teilen.

Einige von ihnen sind mit Dienstleistungen, $ rootScope, Veranstaltungen, lokale Speicher

Ich werde einige Beispiele

Gemeinsame Nutzung von Daten mit geben: $ rootScope

module.controller('Controller5a',function($scope,$rootScope) { 
    $scope.shared='hello'; 
    $scope.$watch('shared',function(newValue){ 
    $rootScope.shared=$scope.shared 
    }) 
}); 

module.controller('Controller5b', function($scope,$rootScope) { 
    $scope.shared='' 
    $rootScope.$watch('shared',function(newValue){ 
    $scope.shared=$rootScope.shared; 
}) 
}); 

http://jsfiddle.net/adutu/rs4tg6qx/41/

Dies wird nicht empfohlen, weil Sie verschmutzen die $ rootScope

Gemeinsame Nutzung von Daten mit: Dienst

weil Dienste und Fabriken Singletons sind, dann können Sie das tun

module.service('Share', function(){ 

    return { text: 'hello' }; 
}); 

module.controller('Controller5a',function($scope, Share) { 
    $scope.Share = Share 

}); 

module.controller('Controller5b', function($scope, Share) { 
    $scope.Share = Share 

}); 

http://jsfiddle.net/adutu/rs4tg6qx/55/ mit Fabrik http://jsfiddle.net/adutu/osd0sm9q/ mit Service

, wenn Sie Möchten Sie in diesem Beispiel Service anstelle von Factory verwenden, ändern Sie einfach die Factory in Service und Sie sind :) und

module.factory('Share', function(){ 
    var text ='hello'; 
    return { 
    get: function(){ 
     return text; 
    }, 
    set: function(value){ 
     text=value; 
     console.log(text); 
    }, 
     value:text 
    }; 
}); 

module.controller('Controller5a',function($scope, Share) { 
    $scope.text = Share.get(); 
    $scope.set = function(){ 
    Share.set($scope.text); 
    } 
}); 

module.controller('Controller5b', function($scope, Share) { 
    $scope.Share = Share;//to bind 
    //use $scope.text = Share.get() //not to bind 
}); 

http://jsfiddle.net/adutu/s9obvz57/1/

Freigabe erhalten

oder diese mit Satz getan Daten mit: Mit Veranstaltungen

module.controller('Controller5a',function($scope) { 
    $scope.text='hello'; 
    $scope.$watch('text',function(newValue,oldValue){ 
    //console.log(newValue); 
    //this with send the message to $rootScope 
    $scope.$emit('share',$scope.text); 
    }) 
}); 

module.controller('Controller5b', function($scope,$rootScope) { 
    $rootScope.$on('share', function(event,response){ 
    console.log(response); 
    $scope.text = response; 
    }) 
}); 

http://jsfiddle.net/adutu/6bo1ojn1/11/

+0

Einige gute Beispiele und Info, aber es gibt ein Problem. Sie binden Ihren Service direkt an Ihren '$ scope'. Dies sollte vermieden werden, alle Änderungen, die Sie an diesem Objekt vornehmen, zum Beispiel hinzufügen/löschen, werden an alle anderen Entitäten weitergegeben, die diesen Dienst verwenden, was offensichtlich nicht gut ist. Es hilft auch, diese Trennung beizubehalten. In Ihrem Beispiel erwähnen Sie den Service, verwenden aber eine Fabrik. Nicht versuchen, es zu Fall zu bringen, nur für jemanden neu zu eckigen erwähnen. – ste2425

+0

@ ste2425 Sie haben Recht, es sollte vermieden werden, wenn Sie nicht die automatische Bindung wollen. Es ist nur so oft, dass du es willst, also ist es der einfachste Weg. Factory und Service machen dasselbe, außer dass die Art und Weise durch eckig instanziiert wird, so dass es sicher ist anzunehmen, dass beide als Services verwendet werden. Sie können mehr hier lesen, wenn Sie interessiert sind http://blog.Thoughtram.io/angular/2015/07/07/Service-VS-Factory-once-and-for-All.html – adutu

+1

@ ste2425 Ich habe die bearbeitet Service Beispiel ein wenig, so dass es für die Anfänger nicht verwirrend ist :) – adutu

Verwandte Themen