0

OK, I'm 1-day new to AngularJS, so this has to be ultra-basic (I hope not an ignorant one about how AngularJS works - I admit MVC is not really my thing, but anyway...).

My Code :

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

PP.controller('documentController', function ($scope) {
    $scope.documents = [
        {
            'filename': 'Untitled-1',
            'content': 'Content-1'
        },
        {
            'filename': 'Untitled-2',
            'content': 'Content-2'
        },
        {
            'filename': 'Untitled-3',
            'content': 'Content-3'
        },
    ];
});

So, I have declared a module (PP), with a controller (documentController) and a property(?) in it (documents).


So, I have 2 questions :

  • How (any possible way is welcome) could I programmatically have access to and change the documents array? (insert/remove/etc)
  • How can I set up an event which fires up when the array has been changed, e.g. an element has been inserted?
Dr.Kameleon
  • 22,532
  • 20
  • 115
  • 223
  • http://stackoverflow.com/questions/17417597/angularjs-watch-array-of-objects-for-data-change ? – Abdul Jabbar Sep 09 '14 at 05:53
  • @AbdulJabbar Well, yes. I believe this one addresses the issue of *watching* for changes pretty well. What about accessing/changing variables programmatically? – Dr.Kameleon Sep 09 '14 at 05:55

2 Answers2

3

Accessing the array

In your controller, you just use:

$scope.documents.push({filename: 'Another', content: 'Document'})

You can do that in any controller function because the array is a variable shared in the scope. Since it's in the scope, you can also access it in your view like so:

<button ng-click="documents.push({filename: 'Another', content: 'Document'})">
  Add document
</button>

Usually, I'd define convenience functions for this behavior in the controller to be used in views, but in this simple example, this should do.

Detecting changes in the array

To watch changes in a collection, you can use $scope.$watchCollection:

$scope.$watchCollection('documents', function(newDocuments, oldDocuments) {
  // do something when the documents array changes
});

For a comparison between $watch and $watchCollection, see Scope $watch() vs. $watchCollection() In AngularJS.

Note that watches can be tricky: It's not always trivial to detect changes correctly, in my experience those functions are called way more often than they should.

Depending on your use-case, you might get by without any watches (Angular provides many ways to react on changes without using a single watch), and you probably shouldn't use $watch in your controllers anyway.

awendt
  • 13,195
  • 5
  • 48
  • 66
  • Thanks a lot. However, my question regarding the first part is a bit different: I'm creating a Cocoa/Objective -> JS/Angular bridge, so I'm looking for a way to programmatically access the controller property from the "outside". Something like `PP.documentController.documents.push(...)`. Is something like that possible, or am I missing something? – Dr.Kameleon Sep 09 '14 at 06:01
  • Oh, wow. That's a whole different story. With Angular loaded, you can do something like `angular.element(document.querySelector('[ng-app=theApp]')).scope()` to get to the scope from the outside but I'm not sure if that helps in your case... – awendt Sep 09 '14 at 06:07
1

You access documents the same way you'd access any other javascript array. Meaning the usual operations are available.

This is how you listen for changes:

$scope.$watchCollection('documents', function(val){
    // documents have changed!
});
CodePrimate
  • 6,646
  • 13
  • 48
  • 86
  • Thanks a lot. But how can I refer to the `documents` array of the `documentController` of the `PP` module then? – Dr.Kameleon Sep 09 '14 at 05:56
  • What do you mean ? Do you want access to documents from other parts of your application? It sounds to me like you need to read up on the MVC pattern a bit. – CodePrimate Sep 09 '14 at 05:59
  • Well, perhaps you have a point here. Or, maybe my decision to try AngularJS for this very project I'm currently working on is quite an overkill... :-) – Dr.Kameleon Sep 09 '14 at 06:02