1

Я пытаюсь передать данные между контроллерами с сервисом, но у меня возникают проблемы, поскольку он ничего не возвращает.Как передавать данные между контроллерами с сервисом в Angular

Вот моя служба:

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; 
     } 
    }; 

}); 

Вот контроллер сохранения данных, используя функцию, называемую goToAccount():

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" 
     } 
    } 
]); 

А вот контроллер, который получает данные. myService.get() возвращает пустое пространство:

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(); 
    } 
]); 

Функция goToAccount срабатывает в HTML с нг-клик:

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

Что я делаю неправильно? Есть ли более простой способ передачи данных между контроллерами? Заранее спасибо.

+2

Вы себе tting 'this.savedData', который является контекстом вашей службы, другими словами, устанавливая свойство вашей службы. Однако возвращаемая вами 'savedData', которая является обычной переменной, не является частью вашей службы. Либо используйте 'this' как для get, так и для set или опустить его для обоих. Не смешивайте и не смешивайте. Вы смотрите на два разных 'savedData', если это имеет смысл. – ste2425

+0

Если я возвращаю this.savedData, он возвращает undefined? –

+0

'this.savedData = data' относится к контексту, в котором вы вызываете эту услугу. Просто используйте 'savedData = data' – Purushoth

ответ

0

Ваш сервис есть опечатка

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; 
     } 
    }; 

}); 

Вы устанавливаете значение в this.savedData но вы объявили как var и вы возвращаете savedData который "".

+1

Я думаю, что вы перепутались с контекстными услугами. В настоящее время это исключает неопределенное исключение в 'savedData'. [См] (https://jsfiddle.net/n9cg1emm/1/). Контекст вашего '.service' отличается от контекста возвращаемого объекта. Просто FYI не всегда лучше использовать фабрику, это две разные вещи для двух разных вариантов использования. Услуги - это одиночные игры, их «экземпляр» будет передаваться через ваше приложение. Заводов нет. – ste2425

+0

Можете ли вы объяснить, почему скрипка с вашим сервисом не работает? Я внедряю это неправильно? – ste2425

+1

Хорошо, получилось, см. Сейчас – Rakeschand

0

Если вы используете сервисные услуги, то он всегда возвращает только массив.

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; 
     } 


}); 

знать и узнать об услугах, смотрите этот youtube video

Внутри вашего chatController

сделать это, чтобы проверить, что она работает или не нравится, что

myService.setsavedData("welcome");

внутри ваш аккаунтCtrl

здесь пытаются вернуть значение прием в боевой готовности

alert(myService.getsavedData());

+0

Затем он возвращает пустой массив. –

+0

НЕТ, вы видите в функции ** (данные) ** вы передаете такой параграф как «myService.setsavedData (« hello »)' в одном ctrl и пытаетесь вызвать 'myService.getsavedData()' в другом ctrl он будет работать –

+0

внутри вашего setsaveData обновить мой ответ, пожалуйста, посмотрите его –

1

Так что ваши работает в области видимости против контекста вопроса. Больная попытка объяснить

сеттер

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

ищет в вашем контексте услуг, или ваш сервис это сам для свойства savedData. Если вы используете в своих методах обслуживания, он будет раскрывать это свойство в вашем сервисе. Таким образом, вы можете получить доступ к нему в своем контроллере с помощью myService.savedData или даже установить его там для этого.

Поглотитель:

get: function() { 
    return savedData; 
    } 

ли просто ссылки на нормальную переменную, но не слишком уверен, с верхней части моей головы, если его закрытия или лексического обзорное (наклоняется к lexcial), что делает эту работу. В любом случае JavaScript сначала рассмотрит метод set для savedData, если он не сможет найти его, он вернется к объявлению сервиса, в котором вы первоначально установили var savedData = "";, и вместо этого используйте эту переменную.

Так как вы можете видеть, что ваша служба использует два разных метода: savedData для каждого метода.

Вы должны либо использовать this для обоих, раскрывая базовое свойство данных своей службы. Если это приемлемо, вы можете также освободить геттер и сеттеры и просто получить доступ к собственности напрямую.

example

Или опустить this и иметь savedData частного к вашим услугам и только она доступна внутри службы.

example


EDIT

Это для основного вопроса с вашей службой, однако я думаю, что @MMhunter может быть на что-то с его комментарием. Вы говорите, что когда вы правильно реализуете сервисы, это все равно не работает. Тем не менее вы перенаправляетесь на другую страницу после установки значения услуги. Если вы не поддерживаете состояние своего приложения на этой странице, перезагрузите, тогда ваше угловое приложение «перезагрузится» на новой загрузке страницы, потеряв все данные, установленные в службе. Одностраничные приложения, которые работают так, не перезагружают всю страницу, они используют частичные и хэш-символы url для загрузки нового частичного, это означает, что вся страница не перезагружается, и поэтому ваше приложение не перезагружает потерянное состояние. Существует альтернатива тому, что ваше приложение поддерживает состояние между загрузками страниц и использует local/sessionStorage. Не знаю, дизайн вашего приложения, возможно, не подходит.

2

Существует несколько способов совместного использования данных между контроллером или компонентами.

Некоторые из них используют услуги, $ rootScope, события, локальное хранение

Я дам несколько примеров

обмене данными с: $ 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/

Это не рекомендуется, поскольку вы загрязняете окружающую среду в Обмен данными $ rootScope

с: службы

потому, что услуги и фабрики одиночек, то вы можете сделать это

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/ с завода http://jsfiddle.net/adutu/osd0sm9q/ с обслуживанием

если вы хотите использовать сервис вместо фабрики в этом примере, просто измените завод на обслуживание и вы сделали :)

или это с набором и получить

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/

обмене данными с: С событий

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

Некоторые хорошие примеры и info, однако есть одна проблема. Прямая привязка вашего сервиса к вашей области $. Этого следует избегать, любые изменения, которые вы вносите в этот объект, добавляет/удаляет свойства, например, будут распространены на все другие объекты, использующие эту службу, что явно не очень хорошо. Это также помогает сохранить это разделение. В вашем примере вы упоминаете сервис, но используете фабрику. Не пытайтесь сбить его, просто упомянув для кого-то нового угловатого. – ste2425

+0

@ ste2425 вы правы, его следует избегать, если вы не хотите автоматического связывания. Это просто много раз, когда вы этого хотите, так что это самый простой способ. Фабрика и сервис делают то же самое, за исключением того, что способ создается путем углового, поэтому можно с уверенностью предположить, что оба они используются как сервисы. Вы можете прочитать больше здесь, если вам интересно http://blog.thoughtram.io/angular/2015/07/07/service-vs-factory-once-and-for-all.html – adutu

+1

@ ste2425 Я отредактировал немного пример обслуживания, поэтому он не путает для начинающих :) – adutu

Смежные вопросы