我试图通过扩展示例应用来使用firebase来学习角度。我想修改用于调用firebase而不是我的webserver的服务对象。我试图将$scope
注入我的服务对象,现在收到错误。我做错了什么?
var app = angular.module("myApp", ['ngRoute', 'firebase']);
app.config(function($routeProvider) {
$routeProvider.when('/', {
templateUrl: "templates/home.html",
controller: "HomeController"
})
.when('/settings', {
templateUrl: 'templates/settings.html',
controller: 'SettingsController'
})
.otherwise({ redirectTo: '/' });
});
//services must return objects
app.service('mailService', ['$scope', '$http', '$firebase', function($scope, $http, $firebase) {
var mailRef = new Firebase("https://ng-book-email-client.firebaseio.com/mail");
//var getMail = function() {
// return $http({
// method: 'GET',
// url: '/api/mail'
// });
//};
$scope.email = $firebase(mailRef);
var sendEmail = function(mail) {
//var d = $q.defer();
//$http({
// method: 'POST',
// data: 'mail',
// url: '/api/send'
//}).success(function(data, status, headers) {
// d.resolve(data);
//}).error(function(data, status, headers) {
// d.reject(data);
//});
//return d.promise;
return $scope.email.$add(mail);
};
return {
//getMail: getMail,
sendEmail: sendEmail
};
}]);
app.controller('HomeController', function($scope) {
$scope.selectedMail;
$scope.setSelectedMail = function(mail) {
$scope.selectedMail = mail;
};
$scope.isSelected = function(mail) {
if($scope.selectedMail) {
return $scope.selectedMail === mail;
}
};
});
// directive that builds the email listing
app.directive('emailListing', function() {
var url = "http://www.gravatar.com/avatar/";
return {
restrict: 'EA', // E- element A- attribute C- class M- comment
replace: false, // whether angular should replace the element or append
scope: { // may be true/false or hash. if a hash we create an 'isolate' scope
email: '=', // accept an object as parameter
action: '&', // accept a function as a parameter
isSelected: '&',
shouldUseGravatar: '@', // accept a string as a parameter
gravatarSize: '@'
},
transclude: false,
templateUrl: '/templates/emailListing.html',
controller: ['$scope', '$element', '$attrs', '$transclude',
function($scope, $element, $attrs, $transclude) {
$scope.handleClick = function() {
$scope.action({selectedMail: $scope.email});
};
}
],
// if you had a compile section here, link: wont run
link: function(scope, iElement, iAttrs, controller) {
var size = iAttrs.gravatarSize || 80;
scope.$watch('gravatarImage', function() {
var hash = md5(scope.email.from[0]);
scope.gravatarImage = url + hash + '?s=' + size;
});
iElement.bind('click', function() {
iElement.parent().children().removeClass('selected');
iElement.addClass('selected');
});
}
};
});
app.controller('MailListingController', ['$scope', 'mailService', function($scope, mailService) {
$scope.email = [];
$scope.nYearsAgo = 10;
//mailService.getMail()
//.success(function(data, status, headers) {
// $scope.email = data.all;
//})
//.error(function(data, status, headers) {
//});
$scope.searchPastNYears = function(email) {
var emailSentAtDate = new Date(email.sent_at),
nYearsAgoDate = new Date();
nYearsAgoDate.setFullYear(nYearsAgoDate.getFullYear() - $scope.nYearsAgo);
return emailSentAtDate > nYearsAgoDate;
};
}]);
app.controller('ContentController', ['$scope', 'mailService', '$rootScope', function($scope, mailService, $rootScope) {
$scope.showingReply = false;
$scope.reply = {};
$scope.toggleReplyForm = function() {
$scope.reply = {}; //reset variable
$scope.showingReply = !$scope.showingReply;
console.log($scope.selectedMail.from);
$scope.reply.to = $scope.selectedMail.from.join(", ");
$scope.reply.body = "\n\n -----------------\n\n" + $scope.selectedMail.body;
};
$scope.sendReply = function() {
$scope.showingReply = false;
$rootScope.loading = true;
mailService.sendEmail($scope.reply)
.then(function(status) {
$rootScope.loading = false;
}, function(err) {
$rootScope.loading = false;
});
}
$scope.$watch('selectedMail', function(evt) {
$scope.showingReply = false;
$scope.reply = {};
});
}]);
app.controller('SettingsController', function($scope) {
$scope.settings = {
name: 'harry',
email: "me@me.com"
};
$scope.updateSettings = function() {
console.log("updateSettings clicked")
};
});
错误
Error: [$injector:unpr] http://errors.angularjs.org/1.2.14/$injector/unpr?p0=<div ng-view="" class="ng-scope">copeProvider%20%3C-%20%24scope%20%3C-%20mailService
at Error (native)
at https://ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular.min.js:6:450
at https://ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular.min.js:32:125
at Object.c [as get] (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular.min.js:30:200)
at https://ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular.min.js:32:193
at c (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular.min.js:30:200)
at d (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular.min.js:30:417)
at Object.instantiate (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular.min.js:31:80)
at Object.<anonymous> (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular.min.js:31:343)
at Object.d [as invoke] (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular.min.js:30:452) angular.js:9509
答案 0 :(得分:3)
答案是$ scope不应该注入服务或工厂。它们应该是可重复使用和可共享的。因此,实现所需效果的正确方法是在服务中创建一个$firebase
对象,并返回一个函数,该函数可以将任何变量和范围以及$bind
它们添加到firebase对象。
灵感来自http://plnkr.co/edit/Uf2fB0?p=info
var app = angular.module("myApp", ['ngRoute', 'firebase']);
//services must return objects
app.service('mailService', ['$http', '$firebase', function($http, $firebase) {
var emailRef = new Firebase("https://ng-book-email-client.firebaseio.com/all");
var emails = $firebase(emailRef);
// uses firebase to bind $scope.email to the firebase mail object
var setEmails = function(scope, localScopeVarName) {
return emails.$bind(scope, localScopeVarName);
};
var sendEmail = function(mail) {
return $scope.email.$add(mail);
};
return {
setEmails: setEmails,
sendEmail: sendEmail
};
}]);
app.controller('MailListingController', ['$scope', 'mailService', function($scope, mailService) {
mailService.setEmails($scope, 'emails');
$scope.nYearsAgo = 10;
$scope.searchPastNYears = function(email) {
var emailSentAtDate = new Date(email.sent_at),
nYearsAgoDate = new Date();
nYearsAgoDate.setFullYear(nYearsAgoDate.getFullYear() - $scope.nYearsAgo);
return emailSentAtDate > nYearsAgoDate;
};
}]);
答案 1 :(得分:0)
我认为你不应该向服务注入$scope
,服务可以是实现/支持多个控制器的常用服务,服务不应该知道$scope
(控制器)。但控制器用户服务通过将参数传递给服务方法来完成工作。
mailService.sendEmail($ scope.reply)
不确定为什么你在服务中需要$ scope,
$scope.email = $firebase(mailRef);
你期待这样的事吗,
this.email = $firebase(mailRef);