Angularjs 来自异步服务的绑定值
Angularjs binding value from async service
由于 中的@sehaxx,我解决了几个错误我想在示例中引入异步,如下面的代码,其中变量是异步初始化的,它的值没有反映在视图中。
(function(angular) {
'use strict';
angular.
module('myServiceModule', []).
controller('MyController', ['$scope', 'notify','$log', function($scope, notify, $log) {
this.clickCount = 0;
this.clickLimit = notify.clickLimit();
this.callNotify = function(msg) {
notify.push(msg);
this.clickCount = notify.clickCount();
$log.debug("[controller] Click count is now", this.clickCount, " and limit is ", this.clickLimit);
};
}]).
factory('notify', ['$window','$log', '$timeout', function(win,$log, $timeout) {
var msgs = [];
var clickCounter = 0;
var countLimit = 0;
$timeout( function(){
countLimit = Math.floor(Math.random() * 10)+1;
$log.debug("[service] Click limit initialized at", countLimit);
return countLimit;
}, 10);
return {
clickLimit: function(){
return countLimit;
},
clickCount: function() {
clickCounter = msgs.length;
$log.debug("[service] You are clicking, click count is now", clickCounter, " limit is ", countLimit);
return clickCounter;
},
push: function(msg) {
msgs.push(msg);
clickCounter = msgs.length;
$log.debug("[service] Counter is", clickCounter, " on ", countLimit);
if (msgs.length === countLimit) {
win.alert(msgs.join('\n'));
msgs = [];
}
}
}
}]);
})(window.angular);
中的工作示例
这没有按预期工作的原因是 countLimit
是一个 Primitive,而 Primitive 总是通过 Val 而不是 byRef 传递,所以工厂无法更新以后的价值。
将 countLimit
更改为对象可以解决此问题,因为对象的值是对对象属性的引用。换句话说,我们可以通过Ref。我们只需更新代码以引用对象的子对象 属性 而不是直接引用值,即 countLimit.value
.
工作示例:https://codepen.io/anon/pen/VVmdbE?editors=1111
(function(angular) {
'use strict';
angular.
module('myServiceModule', []).
controller('MyController', ['$scope', 'notify', '$log', function($scope, notify, $log) {
this.clickCount = 0;
this.clickLimit = notify.clickLimit();
this.callNotify = function(msg) {
notify.push(msg);
this.clickCount = notify.clickCount();
$log.debug("[controller] Click count is now", this.clickCount, " and limit is ", this.clickLimit.value);
};
}]).
factory('notify', ['$window', '$log', '$timeout', function(win, $log, $timeout) {
var msgs = [];
var clickCounter = 0;
var countLimit = {
value: 0,
};
$timeout(function() {
countLimit.value = Math.floor(Math.random() * 10) + 1;
$log.debug("[service] Click limit initialized at", countLimit.value);
return countLimit;
}, 10);
return {
clickLimit: function() {
$log.debug("called clickLimit");
return countLimit;
},
clickCount: function() {
clickCounter = msgs.length;
$log.debug("[service] You are clicking, click count is now", clickCounter, " limit is ", countLimit);
return clickCounter;
},
push: function(msg) {
msgs.push(msg);
clickCounter = msgs.length;
$log.debug("[service] Counter is", clickCounter, " on ", countLimit);
if (msgs.length === countLimit.value) {
win.alert(msgs.join('\n'));
msgs = [];
}
}
}
}]);
})(window.angular);
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Example - example-services-usage-production</title>
<script src="https://code.angularjs.org/snapshot/angular.min.js"></script>
<script src="script.js"></script>
</head>
<body ng-app="myServiceModule">
<div id="simple" ng-controller="MyController as self">
<p>Let's try this simple notify service, injected into the controller...</p>
<input ng-init="message='test'" ng-model="message">
<button ng-click="self.callNotify(message);">NOTIFY</button>
<p>(you have to click {{self.clickLimit.value-self.clickCount}} times more to see an alert)</p>
<div>You have clicked {{ self.clickCount }} times</div>
</div>
</body>
</html>
由于
(function(angular) {
'use strict';
angular.
module('myServiceModule', []).
controller('MyController', ['$scope', 'notify','$log', function($scope, notify, $log) {
this.clickCount = 0;
this.clickLimit = notify.clickLimit();
this.callNotify = function(msg) {
notify.push(msg);
this.clickCount = notify.clickCount();
$log.debug("[controller] Click count is now", this.clickCount, " and limit is ", this.clickLimit);
};
}]).
factory('notify', ['$window','$log', '$timeout', function(win,$log, $timeout) {
var msgs = [];
var clickCounter = 0;
var countLimit = 0;
$timeout( function(){
countLimit = Math.floor(Math.random() * 10)+1;
$log.debug("[service] Click limit initialized at", countLimit);
return countLimit;
}, 10);
return {
clickLimit: function(){
return countLimit;
},
clickCount: function() {
clickCounter = msgs.length;
$log.debug("[service] You are clicking, click count is now", clickCounter, " limit is ", countLimit);
return clickCounter;
},
push: function(msg) {
msgs.push(msg);
clickCounter = msgs.length;
$log.debug("[service] Counter is", clickCounter, " on ", countLimit);
if (msgs.length === countLimit) {
win.alert(msgs.join('\n'));
msgs = [];
}
}
}
}]);
})(window.angular);
中的工作示例
这没有按预期工作的原因是 countLimit
是一个 Primitive,而 Primitive 总是通过 Val 而不是 byRef 传递,所以工厂无法更新以后的价值。
将 countLimit
更改为对象可以解决此问题,因为对象的值是对对象属性的引用。换句话说,我们可以通过Ref。我们只需更新代码以引用对象的子对象 属性 而不是直接引用值,即 countLimit.value
.
工作示例:https://codepen.io/anon/pen/VVmdbE?editors=1111
(function(angular) {
'use strict';
angular.
module('myServiceModule', []).
controller('MyController', ['$scope', 'notify', '$log', function($scope, notify, $log) {
this.clickCount = 0;
this.clickLimit = notify.clickLimit();
this.callNotify = function(msg) {
notify.push(msg);
this.clickCount = notify.clickCount();
$log.debug("[controller] Click count is now", this.clickCount, " and limit is ", this.clickLimit.value);
};
}]).
factory('notify', ['$window', '$log', '$timeout', function(win, $log, $timeout) {
var msgs = [];
var clickCounter = 0;
var countLimit = {
value: 0,
};
$timeout(function() {
countLimit.value = Math.floor(Math.random() * 10) + 1;
$log.debug("[service] Click limit initialized at", countLimit.value);
return countLimit;
}, 10);
return {
clickLimit: function() {
$log.debug("called clickLimit");
return countLimit;
},
clickCount: function() {
clickCounter = msgs.length;
$log.debug("[service] You are clicking, click count is now", clickCounter, " limit is ", countLimit);
return clickCounter;
},
push: function(msg) {
msgs.push(msg);
clickCounter = msgs.length;
$log.debug("[service] Counter is", clickCounter, " on ", countLimit);
if (msgs.length === countLimit.value) {
win.alert(msgs.join('\n'));
msgs = [];
}
}
}
}]);
})(window.angular);
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Example - example-services-usage-production</title>
<script src="https://code.angularjs.org/snapshot/angular.min.js"></script>
<script src="script.js"></script>
</head>
<body ng-app="myServiceModule">
<div id="simple" ng-controller="MyController as self">
<p>Let's try this simple notify service, injected into the controller...</p>
<input ng-init="message='test'" ng-model="message">
<button ng-click="self.callNotify(message);">NOTIFY</button>
<p>(you have to click {{self.clickLimit.value-self.clickCount}} times more to see an alert)</p>
<div>You have clicked {{ self.clickCount }} times</div>
</div>
</body>
</html>