Travis Heeter Travis Heeter - 3 months ago 8
AngularJS Question

Calling a method via an array within the same model in which the members are defined

I'm trying to keep all my model functionality in one place. I'd like to be able to call its methods within it:

JS

/**
* This app prints "OK" a number of times, according to which button is pressed
*/
angular.module('myApp', [])
.controller('MyCtrl', ['$scope', function MyCtrl($scope) {

$scope.okModel = {
oks: [],
addOne: function(){
this.oks.push(["OK"]);
},
addTwo: function(){
this.addOK();
this.addOK();
},
buttons: [
{name:"addOK", action: this.addOne}, // THIS is where the issue is I think
{name:"add2OKs", action: this.addTwo}
]
};
}]);


HTML

<div ng-controller="MyCtrl">

<!-- print the object holding all the "OK"s -->
oks: {{okModel.oks}}

<!-- show the buttons -->
<button ng-repeat="item in okModel.buttons" ng-click="item.action()">
{{item.name}}
</button>

<!-- print the "OK"s -->
<div ng-repeat="ok in okModel.oks">
{{ok[0]}}
</div>
</div>


I'm not getting an error, but it's not working either. No "OK"s are being added to the model. It seems like the issue may be with the
okModel.buttons
action property.

Here's a plunker: https://plnkr.co/edit/mDk43yEKSQB37QSmiKJn?p=preview

TL;DR: I realize that the issue is probably with
this
in
buttons
, what should I use instead?




Bonus question: I'm new to angular and realize I may be using models incorrectly. If you know of a better way to do models, please let me know.

Answer

Since you asked, the "angular" way to do this is to have a service provide the model, rather than defining it in your controller:

var app = angular.module('myApp', []);

app.factory('modelService', function ModelService() {
  var okModel = {
    oks: [],
  }
  okModel.addOne = function() {
    okModel.oks.push(["OK"]);
  };
  okModel.addTwo = function() {
    okModel.addOne();
    okModel.addOne();
  };
  okModel.buttons = [{
      name: "addOK",
      action: okModel.addOne
    },
    {
      name: "add2OKs",
      action: okModel.addTwo
    }
  ]

  return okModel;
});

app.controller('MyCtrl', ['$scope', 'modelService', function MyCtrl($scope, modelService) {
  $scope.okModel = modelService;
}]);

Here is a plunk.