实时显示更改值(Angular,JS,OOP)

时间:2016-11-22 10:38:18

标签: javascript html angularjs

所以,现在我正在通过创建某种光文本浏览器游戏来练习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)。任何帮助和建议都会很棒。

3 个答案:

答案 0 :(得分:1)

您的Updated fiddle

问题是您没有更新$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以及如何处理来自单一事实来源的数据。然后您可以使用ng-redux

我尝试过的最佳设置是Redux + RxJs。 (我已经读过可以将ngrx与AngularJs一起使用,而不仅仅是Angular2。)

答案 2 :(得分:0)

更简单

&#13;
&#13;
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;
&#13;
&#13;