如何从一个控制器设置一个服务的值,并使用该服务更新另一个控制器的值
How to set value of one service from one controller, and update value of another controller with this service
我是这个领域的新手,想写一个app,现在遇到了一些问题。这是我的代码的一个简单版本,我想要的是API只显示signUp
第一。在我按下signUp
和submit
后,显示的按钮应该只有signout
我认为我的方法是不对的,因为当我在服务中更改了值后,另一个控制器无法更新它的值。你能告诉我吗?如果可能请使用this.logged
,谢谢!
过程不必与我的标题相同。如果它能实现我的功能就行了。
https://plnkr.co/edit/1ptaVzmD7EwPZ6dU23gR?p =
预览(function(){
angular.module('myApp',['myApp.dashboard','myApp.value','myApp.signUp']);
})();
(function(){
angular.module('myApp.dashboard',[]);
})();
(function(){
angular.module('myApp.value',[]);
})();
(function(){
angular.module('myApp.signUp',[]);
})();
(function(){
'use strict';
angular.module('myApp.dashboard').controller('mainControl',mainControl);
mainControl.$inject = ['whichToShow'];
function mainControl(whichToShow){
this.logged=whichToShow.getVar();
alert(this.logged);
}
})();
(function(){
'use strict';
angular.module('myApp.value').factory('whichToShow',function(){
alert("running2");
var logged=false;
return {
getVar: function(){
return logged;
},
setVar: function(value){
logged=value;
}
};
});
})();
(function(){
'use strict';
angular.module('myApp.signUp').controller('signUpControl',signUpControl);
signUpControl.$inject = ['whichToShow'];
function signUpControl(whichToShow){
alert("haha");
this.logIn=function(){
whichToShow.setVar(true);
alert("running set!");
};
};
})();
部分html:
<body ng-controller="mainControl as mc">
<div>
<div ng-hide="mc.logged">
<button type="button" class="btn" data-toggle="modal" data-target=".signUp">Sign Up</button>
</div>
<div ng-show="mc.logged">
<button>Sign Out</button>
</div>
</div>
<div class="signUp modal fade" id="signUp" ng-controller='signUpControl as sc'>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">sigh up</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">×</button>
</div>
<div class="modal-body">
<form id="signUpForm" name="signUpForm" ng-submit="sc.logIn()">
<label for="email">
<span>email:</span>
<input type="email" name="email">
</label>
<button class="submit" id="signUpSubmit" type="submit" value="signUp">submit</button>
</form>
</div>
<div class="modal-footer">
</div>
</div>
</div>
</div>
</body>
基本上你是在用户点击提交后在工厂对象中设置值,但这并没有反映在UI中,因为你没有更新范围对象this.logged
,所以要告诉主控制器从注册控制器改变this.logged $scope
的值我们可以使用$emit
或$broadcast
除了$watch
的方法,你甚至可以使用$broadcast
来实现这一点。
在你的JS文件controllers中添加下面的代码
signUpControl
(function(){
'use strict';
angular.module('myApp.signUp').controller('signUpControl',signUpControl);
signUpControl.$inject = ['whichToShow','$rootScope'];
function signUpControl(whichToShow,$rootScope){
alert("haha");
this.logIn=function(){
whichToShow.setVar(true);
$rootScope.$broadcast('login');//broadcasting that user has logged in
//alert("running set!");
};
};
})
mainControl
(function(){
'use strict';
angular.module('myApp.dashboard').controller('mainControl',mainControl);
mainControl.$inject = ['whichToShow','$rootScope'];
function mainControl(whichToShow,$rootScope){
var mc = this;
mc.main ={};
mc.main.logged=whichToShow.getVar();
alert(mc.main.logged);
// below code will listen to the broadcast and do the necessary process..
$rootScope.$on('login',function(event,args){
mc.main.logged=whichToShow.getVar();
});
}
})
您需要监视来自服务的日志值的变化。
这就是你所需要做的。
(function() {
angular.module('myApp', ['myApp.dashboard', 'myApp.value', 'myApp.signUp']);
})();
(function() {
angular.module('myApp.dashboard', []);
})();
(function() {
angular.module('myApp.value', []);
})();
(function() {
angular.module('myApp.signUp', []);
})();
(function() {
'use strict';
angular.module('myApp.dashboard').controller('mainControl', mainControl);
mainControl.$inject = ['$scope', 'whichToShow'];
function mainControl($scope, whichToShow) {
$scope.$watch(() => whichToShow.getVar(), (newValue, oldValue) => this.logged = newValue)
}
})();
(function() {
'use strict';
angular.module('myApp.value').factory('whichToShow', function() {
var logged = false;
var service = {};
return {
getVar: function() {
return logged;
},
setVar: function(value) {
logged = value;
}
}
});
})();
(function() {
'use strict';
angular.module('myApp.signUp').controller('signUpControl', signUpControl);
signUpControl.$inject = ['whichToShow'];
function signUpControl(whichToShow) {
this.logIn = function() {
whichToShow.setVar(true);
};
};
})();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<div ng-app="myApp">
<div ng-controller="mainControl as mc">
<div>
<div ng-hide="mc.logged">
<button type="button" class="btn" data-toggle="modal" data-target=".signUp">Sign Up</button>
</div>
<div ng-show="mc.logged">
<button>Sign Out</button>
</div>
</div>
<div class="signUp modal fade" id="signUp" ng-controller='signUpControl as sc'>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">sigh up</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">×</button>
</div>
<div class="modal-body">
<form id="signUpForm" name="signUpForm" ng-submit="sc.logIn()">
<label for="email">
<span>email:</span>
<input type="email" name="email">
</label>
<button class="submit" id="signUpSubmit" type="submit" value="signUp">submit</button>
</form>
</div>
<div class="modal-footer">
</div>
</div>
</div>
</div>
</div>
</div>
Codepen的工作解决方案
您仍然试图在这里设置原语的值,而不是对象属性。在JavaScript中,传递原语的是byValue,而不是byReference,所以whichToShow.getVar();
返回的是true
或false
,而不是返回对logged
的引用。因此,除非再次调用.getVar()
以获得新值,否则不会看到logged
的变化。这就是为什么到目前为止您看到的大多数答案都有某种形式的$watch
, $broadcast
或类似的mc
,以提醒您的CC_20应该再次询问logged
变量的当前值。
如果你想避免使用$watch
,你应该使用对象而不是原语。通过使用一个对象,你可以通过reference 传递对象,这将允许angular看到任何有引用集的属性的变化。
在工厂中,返回一个对象:
(function() {
'use strict';
angular.module('myApp.value').factory('whichToShow', function() {
alert("running2");
var status = {
logged: false
};
var logged = false;
return {
getVar: function() {
return status;
},
setVar: function(value) {
status.logged = value;
}
};
});
})();
在mainControl中,使用对该对象的引用:
(function() {
'use strict';
angular.module('myApp.value').factory('whichToShow', function() {
alert("running2");
var status = {
logged: false
};
return {
getVar: function() {
return status;
},
setVar: function(value) {
status.logged = value;
}
};
});
})();
最后,使用HTML中的object属性:
<div ng-hide="mc.status.logged">
...
<div ng-show="mc.status.logged">
...
https://plnkr.co/edit/Pindt2LYxDxyk8C5Axp1?p =
预览我甚至可以更进一步,直接通过服务返回对象,并跳过getVar
和setVar
函数。
你可以把一些变量全局或在你的根控制器,让说isLoggedIn
现在有一个服务,你可以在signingIn
上设置这个变量,并像这样使用它{
}
- 尝试将服务链接到控制器时出现角度问题
- 使用服务(AngularJS)在控制器之间共享数据
- 从AngularJS中的另一个文件中的控制器访问服务
- AngularJS 1.5.x服务未正确绑定,并且未在控制器中更新
- Ionic将firebase注入工厂,同时将控制器和服务保存在不同的文件中
- 通过共享服务在两个不同ng应用程序中的控制器之间共享数据
- Http服务工厂将未定义的返回到Angular中的控制器
- 由控制器调用的服务更改时,Angular未更新视图
- 将Browserify与Angular JS结合使用--将服务传递到控制器中
- 将工厂服务数据发送到控制器,以便在视图中使用
- 角度控制器服务承诺不起作用
- 跨控制器服务的角度json数据
- 使用DOM中的信息创建一个控制器/服务来持久化数据
- 推迟在应用程序运行angularjs上创建控制器/服务
- 将主机配置传递给控制器/服务
- 控制器/服务的最佳实践
- 控制器+服务结构不能正确触发离子切换ng-change
- 未捕获的TypeError: undefined不是函数'当把控制器/服务放在单独的js文件中时
- 一个AngularJS文件中有多少控制器(服务、工厂、指令)
- 我应该保护我的 Angular 控制器/服务免受全局命名空间的影响吗?