[英]Accessing scope in angular factory
要求是單擊按鈕后顯示成功消息。由於必須在許多控制器中使用此成功消息,因此我決定使用服務來執行此操作。 但是我無法進入范圍
index.html
<div ng-controller="uploadController">
<div class="col-md-6" ng-click="uploadFile()" >
<div class="form-group has-success" id="divsubmitbtn">
<button type="submit" id="submit" class="btn btn-custom"
ng-click="submitData()" ng-disabled="isDisableSubmit">
<span class="glyphicon glyphicon-upload"></span> Upload</button>
</div>
</div>
<div class=" col-md-12">
<div ng-show="showError" ng-class="{fade:doFade}" class="alert alert- success">
<strong>Success:</strong> {{successMessage}}
</div>
</div>
</div>
controller.js
app.controller('uploadController', ['$scope','$timeout','$rootScope','displayMsgService',function($scope,$timeout,$rootScope,displayMsgService) {
$scope.uploadFile = function($scope,displayMsgService){
$scope.displayMsgService.show();
};
$rootScope.submitData = function() {
$scope.uploadFile();
};
}]);
service.js
app.factory('displayMsgService',function() {
return {
show : function($scope){
$scope.showError = false;
$scope.doFade = false;
$scope.showError = true;
$scope.successMessage = "success";
$timeout(function(){
$scope.doFade = true;
}, 2500);
}
}
});
我收到以下錯誤, 無法讀取未定義的屬性“ displayMsgService”
我錯過了什么
打字機
$rootScope.submitData = function() {
$scope.uploadFile();
};
我認為您的意思是: $scope.submitData
,因為submitData
是控制器中的$ scope方法;
和$scope.displayMsgService.show();
應該確實是displayMsgService.show();
,因為displayMsgService
是注入的服務,與$ scope不相關(不是控制器作用域方法)
在您的控制器中,嘗試:
$scope.uploadFile = function($scope,displayMsgService){
displayMsgService.show($scope);
};
工廠函數的編寫方式必須通過控制器范圍; 如果您從工廠修改范圍,則還需要調用$scope.$apply()
;
說明
show : function($scope)
並不意味着將范圍注入到您的工廠方法中。 相反,這意味着必須向show函數傳遞參數。 您可以將show : function($scope)
替換為show : function(arg)
並獲得相同的結果。
這就是為什么必須像這樣通過控制器傳遞您的范圍的原因: displayMsgService.show($scope)
但是, 將控制器$ scope傳遞給工廠/服務不是一個好習慣 :請參閱以下文章:將當前范圍傳遞給AngularJS服務並將范圍注入服務
為避免將范圍傳遞給服務,這里有兩種解決方案:
在您的情況下,最簡單的方法是從服務中廣播事件,以使您的控制器知道文件已上傳,如下所示:
$rootScope.$broadcast('uploadDone');
注意:同樣, $rootScope
需要在服務/工廠中注入
並在您的控制器中:
$scope.$on('uploadDone',function(){
//modify $scope here
}
對於上傳等異步事件,您也可以考慮使用Promise。 即使它們不像廣播那樣簡單,但在這種情況下,它們仍是標准做法。
在您的控制器中:
uploadMsgService.upload()
.then(function{
//do something to $scope
});
並為您服務:
app.factory('uploadMsgService',function($q) {
var deferred = $q.defer();
doTheUpload(inputData,function(err,data){
if(err){deferred.reject("there was an error:"+err);}
deferred.resolve(data);
})
return deferred.promise;
});
有關在angularjs中使用promise的更多信息:
您可以嘗試使用基本控制器代替服務。
基本控制器
app.controller('DisplayMsgController', ['$scope', function ($scope) {
$scope.show = function () {
// Set all your required variables and messages here
};
}]);
然后,您只需要將基本控制器包含在需要所需功能的任何控制器中。
上傳控制器
app.controller('UploadController', ['$scope', '$controller', function ($scope, $controller) {
// Pass the scope to the controller
$controller('DisplayMsgController', { $scope: $scope });
// Do your processing of data and then call the DisplayMsgController's function
// As you would any other function in the current controller
$scope.uploadFile = function(){
// Do processing here
...
// Display message
$scope.show();
};
}]);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.