1

I am having a situation like in this post here only that I not only need to fetch the element, but change its e.g. name value.

I already found out that one could do it like that:

dataList.splice(index, 1);
dataList.splice(index, 0, newItem);

But there are several problems. I know the id but if I am manipulating the array from time to time I will loose track of the index <=> id correlation because with this method i will take out items, change them and push them as a "new" one, right? But that is kind of not really elegant and could cause problems I think.

Basically I just want to toggle a visible attribute which then should change in the array. Here is the array:

$scope.cLines = [{ id: 1, cColor: 'red', cName: 'Entryline right', visible: true }];

Of course there are usually more elements inside, but I left one for simplicity reasons.

The visible toggler should be working like that (naiv "pseudocode" which would be really awesome if it would work like that simple :) )

$scope.cLines[id === id].visible = !$scope.cLines[id === id].visible;

Second best thing would be if I could access the element directly with the filter, is that possible?

Thank you in advance.

Community
  • 1
  • 1
  • How are you triggering the visibility change? – Cerbrus Jun 29 '15 at 14:36
  • Take a look at angular extend https://docs.angularjs.org/api/ng/function/angular.extend, may be of help – Jax Jun 29 '15 at 14:39
  • There is a button on the page which executes a function where I want to set the parameter to the opposite(true/false). Based on that a ng-show either shows a definde element or not. I am looking into that extend functionality but doesn't seem that it will help. thank you – christian1337 Jun 29 '15 at 14:45

2 Answers2

2

There are several ways to go about it. One is to use filter().

var id = 1;
var visibility = true;

var items = $scope.cLines.filter(function(item) {
    return item.id === id;
});
if (items.length >= 1) items[0].visible = visibility;

You can wrap that into a function:

function setVisibility(arr, id, visibility) {
    var items = arr.filter(function(item) {
        return item.id === id;
    });
    if (items.length >= 1) items[0].visible = visibility;
}

Then use it like this:

setVisibility($scope.cLines, 1, true);

You could also update $scope.cLines into a more complex object, instead of just an array:

$scope.cLines = {
    "item" : function (id) {
        var items = this.lines.filter(function(item) {
            return item.id === id;
        });
        if (items.length >= 1) 
            return items[0];
        else
            return new Object(); //or throw an error
    },
    "lines" : [
        { id: 1, cColor: 'red', cName: 'Entryline right', visible: true }
        //....and more
    ]
};

Then use it like this:

$scope.cLines.item(1).visible = true;

With this, make sure to use $scope.cLines.lines if you have to loop through it.

jwatts1980
  • 7,254
  • 2
  • 28
  • 44
0

I'm not sure I fully understand the question, so if I'm off here, perhaps you can clarify what you're trying to do.

If you have an ng-repeat and you're trying to toggle some value in the current object, just pass that object to the ng-click function:

<button ng-click="changeVisible(line);" ng-repeat="line in cLines">Visible = {{line.visible}}</button>

and then in your controller, you'd have something like this:

$scope.changeVisible = function(obj) {
    obj.visible = !obj.visible;
  }

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

app.controller('DemoCtrl', function($scope) {
  $scope.cLines = [{
    id: 1,
    cColor: 'red',
    cName: 'Entryline right',
    visible: true
  }, {
    id: 2,
    cColor: 'blue',
    cName: 'Entryline right',
    visible: false
  }];

  $scope.changeVisible = function(obj) {
    obj.visible = !obj.visible;
  }

});
<script src="https://code.angularjs.org/1.3.16/angular.js"></script>
<div ng-app="demo">
  <div ng-controller="DemoCtrl">
    <button ng-click="changeVisible(line);" ng-repeat="line in cLines">Visible = {{line.visible}}</button>
  </div>
</div>
jme11
  • 17,134
  • 2
  • 38
  • 48
  • I previously did it like that, but what if I want to change the name? Or if I want to change it "programmatically" only in the controller? – christian1337 Jun 29 '15 at 16:17
  • It's an object, so if you want to change a property value, just tell it what the new value should be. In the example above, you could just change the function to: obj.name = "some new name". If you want to add a completely new property, just define it: obj.mynewproperty = "newval". I'm not really sure what you mean by change it programmatically. Maybe you can give me an example scenario. – jme11 Jun 29 '15 at 16:24