0

I am looking for a way to synchronize arrays within an AngularJS controller.

Example:

var input = [1];
var synchArray = DatabindToModifiedInput() 
// synchArray is something like this:
// [{name:someObject}, {name:inputElement, Id:1}]

input.push(2);
// synchArray should be updated automatically:
// [{name:someObject}, {name:inputElement, Id:1}, {name:inputElement, Id:2}]

Obviously i could register $watches and modify synchArray when input changes but that doesn't feel very angular-like.

Question:

I am tempted to write a filter which i can apply to the input-array. However this still feels like i am missing some obvious way to bind the data together within a controller/service.

Is there some way to utilize ngRepeat or some databinding-mechanism for this? Or should i maybe approach this in a completely different way?

2
  • Why are you trying to do this, what's the end goal? If we understood where you were going with it we may be able to suggest a better approach Commented May 20, 2016 at 7:20
  • I would like to bind synchArray to the view with ng-repeat. This data is dependant on arrays which are managed by several different services though and it felt wrong to use several ng-repeats doing basically the same when i could "just" merge the data beforehand. Commented May 20, 2016 at 8:19

1 Answer 1

0

You should likely make an extended array object as demonstrated in this post by Jacob Relkin.

That way you could do more than just one array or event when something happens.

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

function MyCtrl($scope) {

  $scope.myClonedArray = [];
  $scope.myExtendedArray;

  // Extended array type
  function EventedArray(handler) {
    this.stack = [];
    this.mutationHandler = handler || function() {};
    this.setHandler = function(f) {
      this.mutationHandler = f;
    };
    this.callHandler = function(event, obj) {
      if (typeof this.mutationHandler === 'function') {
        this.mutationHandler(event, obj);
      }
    };
    this.push = function(obj) {
      this.stack.push(obj);
      this.callHandler('push', obj);
    };
    this.pop = function() {
      var obj = this.stack.pop();
      this.callHandler('pop', obj);
      return obj;
    };
    this.getArray = function() {
      return this.stack;
    }
  }

  var handler = function(event, item) {
    console.log(event, item);
    if (event === 'push') {
      $scope.myClonedArray.push(item);
    } else if (event === 'pop') {
      $scope.myClonedArray.pop();
    }
  };

  $scope.myExtendedArray = new EventedArray(handler);

  //or 

  // $scope.myExtendedArray = new EventedArray();
  // $scope.myExtendedArray.setHandler(handler);

  $scope.addItem = function() {
    $scope.myExtendedArray.push($scope.inputValue);
  };

  $scope.popItem = function() {
    $scope.myExtendedArray.pop();
  };


}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>


<html ng-app="myApp">

<body ng-controller="MyCtrl">

  <input type="text" ng-model="inputValue" />
  <button ng-click="addItem()">Add</button>
  <button ng-click="popItem()">Pop</button>

  <p>Custom Array</p>
  <ul>
    <li ng-repeat="item in myExtendedArray.stack  track by $index">
      {{item}}
    </li>
  </ul>

  <p>Cloned Array</p>
  <ul>
    <li ng-repeat="item in myClonedArray  track by $index">
      {{item}}
    </li>
  </ul>

</body>


</html>

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.