所以,现在我正在通过创建某种光文本浏览器游戏来练习JS / OOP / Angular :)陷入了简单的情况(总是如此)。我稍微简化了我的代码,这里是:https://jsfiddle.net/gjgjc3fx/1/。所以我刚刚创建了一个班级'英雄使用工厂:
angular.module('myGame', [])
.factory('Hero', function() {
function Hero(name, damage) {
this.name = name;
this.damage = damage;
}
Hero.prototype = {
talk : function() {
alert('Hi, my name is: ' + this.name + ', my current damage is: ' + this.damage);
},
addDamage : function(damage) {
this.damage += damage;
console.log(this.damage);
}
}
return Hero;
})
然后在控制器中使用它:
.controller('myGameCtrl', function($scope, Hero) {
var am = new Hero('AntiMage', 70);
$scope.currentDamage = am.damage;
$scope.hi = function() {
am.talk();
}
$scope.add50Dmg = function() {
am.addDamage(50);
}
})
HTML:
<div ng-app='myGame' ng-controller='myGameCtrl'>
<div>{{currentDamage}}</div>
<button ng-click='add50Dmg()'>Add 50 damage</button>
<div ng-click='hi()'>Hi</div>
</div>
问题是 - 如果我想实时看到<div>{{currentDamage}}</div>
不断变化的伤害,我想解决什么?我的意思是,如果我点击按钮它将增加50点伤害,我可以看到警报窗口的变化,但<div>{{currentDamage}}</div>
一直保持不变(70)。任何帮助和建议都会很棒。
答案 0 :(得分:1)
问题是您没有更新$scope.currentDemage
。要更新$scope.currentDemage
,您必须从Hero
工厂获得价值。
在工厂中添加getDamage
功能,如
Hero.prototype = {
talk : function() {
alert('Hi, my name is: ' + this.name + ', my current damage is: ' + this.damage);
},
addDamage : function(damage) {
this.damage += damage;
console.log(this.damage);
},
/* getDamage function */
getDamage : function(){
return this.damage;
}
}
将工厂实例分配给ngController中的$scope
变量,如
$scope.myService = am;
// watch getDamage() function for binding new Value.
$scope.$watch('myService.getDamage()',function(newvalue){
$scope.currentDamage = newvalue;
})
答案 1 :(得分:1)
所以已经有两个答案,是的,他们会工作。
但我想告诉你如何制作它的反应性版本(例如你使用Angular2)。
首先,这是您的代码工作Plunkr。
编辑:我更新了Plunkr以向您展示如何使用component
代替controller
,并创建了多个游戏实例,以便您可以看到它已经很好地同步;)!
说明:
定义应用
let app = angular.module('myGame', []);
定义Heroes
工厂
app.factory('Heroes', function() {
// ---------------------------------------------
// ---------------- observable -----------------
// ---------------------------------------------
let heroesFactoryObserver;
let heroesFactory$ = new Rx.Observable.create((observer) => {
heroesFactoryObserver = observer;
})
.share();
// data to subscribe from controller
let data = {};
// ---------------------------------------------
// ------------------- Hero --------------------
// ---------------------------------------------
let heroId = 0;
let Hero = function(name, damage) {
this.id = heroId++;
this.name = name;
this.damage = damage;
this.hi = () => {
alert('Hi, my name is: ' + this.name + ', my current damage is: ' + this.damage);
};
// default damage : 10
this.addDamage = (damage = 10) => {
this.damage += damage;
heroesFactoryObserver.next(data);
};
};
// ---------------------------------------------
// -------------- Data to share ----------------
// ---------------------------------------------
data = {
// the observable to subscribe to data change
heroesFactory$,
// whenever you need to force update, for example when
// the app is loaded and you want to get data for the first time
update: () => heroesFactoryObserver.next(data),
// your array of heroes
heroes: [],
// create a new hero and add him to heroes array
createHero: (name, damage) => data.heroes.push(new Hero(name, damage))
};
return data;
});
定义controller
app.controller('myGameCtrl', function($scope, Heroes) {
// whenever a heroe his updated
Heroes.heroesFactory$.subscribe(h => {
$scope.heroes = h.heroes;
});
// load data once by asking Heroes to trigger a change
// so that every other component can update too
Heroes.update();
});
肯定会更加冗长。但它是否强迫你使用setter(所以你可以触发observer.next()
),你可以将它用作钩子并在这里做你想要的。另外,不是使用角度表并且在手表中具有逻辑(您需要为要查看数据的每个组件复制),您可以通过工厂获得一个源。
我尝试过的最佳设置是Redux + RxJs。 (我已经读过可以将ngrx与AngularJs一起使用,而不仅仅是Angular2。)
答案 2 :(得分:0)
更简单
angular.module('myGame', [])
.controller('myGameCtrl', function($scope) {
var vm = $scope ;
vm.currentdamage = 20;
// currentdamage = 20;
vm.add50Dmg=function(){
vm.currentdamage = vm.currentdamage +50;
};
})
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='myGame' ng-controller='myGameCtrl'>
<div>tst {{currentdamage}}</div>
<button ng-click='add50Dmg()'>Add 50 damage</button>
<div ng-click='hi()'>Hi</div>
</div>
&#13;