admin管理员组

文章数量:1026463

I'm trying to achieve an array with items that displays as a title and image and when the user click the title the item should be added to a div. However, I can´t make it to work as when I click on "Add me", there is only a blank item added, with no image and no title. I got the delete-function to work but not the add-function.

Here is what I got: The "Add me"-button and the list of items

    <li ng-repeat="item in items.data">
        <a href="#">{{item.title}}</a> <img ng-src="{{ item.image }}" /><a ng-click="deleteItem($index)" class="delete-item">x</a>
        <button ng-click="addItem()">Add Me</button>
    </li>

The array

var myApp = angular.module("myApp", []);
myApp.factory("items", function () {
var items = {};
items.data = [{
    title: "Item 1",
    image: "img/item01.jpg"
}, {
    title: "Item 2",
    image: "img/item02.jpg"
}, {
    title: "Item 3",
    image: "img/item03.jpg"
}, {
    title: "Item 4",
    image: "img/item04.jpg"
}];
  return items;
});

And the functions for add and delete

function ItemsController($scope, items) {
$scope.items = items;

$scope.deleteItem = function (index) {
    items.data.splice(index, 1);
}
$scope.addItem = function () {
    items.data.push({
        title: $scope.items.title
    });
 }
}

I'm trying to achieve an array with items that displays as a title and image and when the user click the title the item should be added to a div. However, I can´t make it to work as when I click on "Add me", there is only a blank item added, with no image and no title. I got the delete-function to work but not the add-function.

Here is what I got: The "Add me"-button and the list of items

    <li ng-repeat="item in items.data">
        <a href="#">{{item.title}}</a> <img ng-src="{{ item.image }}" /><a ng-click="deleteItem($index)" class="delete-item">x</a>
        <button ng-click="addItem()">Add Me</button>
    </li>

The array

var myApp = angular.module("myApp", []);
myApp.factory("items", function () {
var items = {};
items.data = [{
    title: "Item 1",
    image: "img/item01.jpg"
}, {
    title: "Item 2",
    image: "img/item02.jpg"
}, {
    title: "Item 3",
    image: "img/item03.jpg"
}, {
    title: "Item 4",
    image: "img/item04.jpg"
}];
  return items;
});

And the functions for add and delete

function ItemsController($scope, items) {
$scope.items = items;

$scope.deleteItem = function (index) {
    items.data.splice(index, 1);
}
$scope.addItem = function () {
    items.data.push({
        title: $scope.items.title
    });
 }
}
Share Improve this question edited Jan 15, 2015 at 2:58 PSL 124k21 gold badges256 silver badges243 bronze badges asked Jan 14, 2015 at 21:47 pistevwpistevw 4326 silver badges17 bronze badges 3
  • What is $scope.items.title ? – PSL Commented Jan 14, 2015 at 21:50
  • Why is there two add buttons? – Wayne Ellery Commented Jan 14, 2015 at 21:56
  • I tried to use {{item.title}} to display the title from the list, but with no luck. – pistevw Commented Jan 14, 2015 at 21:59
Add a ment  | 

1 Answer 1

Reset to default 4

You need to pass the item under iteration.

<button ng-click="addItem(item)">Add Me</button>

and add the title to the newly added:

  $scope.addItem = function(item) {
    items.data.push({
      title: item.title
    });
  }

it is better not to use $index (it can cause issue when used with filters eg: orderBy filter) instead just pass the item to delete and:

   $scope.deleteItem = function(item) {
     items.data.splice(items.indexOf(item), 1);
   }

You also have an invalid html, li must be a child of ul or ol.

A sample implementation:

 function($scope, items) {
  $scope.items = items;
  $scope.cart = [];

  $scope.deleteItem = function(item) {
    var cart = $scope.cart;
    //Get matched item from the cart
    var match = getMatchedCartItem(item);
    //if more than one match exists just reduce the count
    if (match.count > 1) {
      match.count -= 1;
      return;
    }
    //Remove the item if current count is 1
    cart.splice(cart.indexOf(item), 1);
  }

  $scope.addItem = function(item) {
    //Get matched item from the cart
    var match = getMatchedCartItem(item), itemToAdd ;
     //if item exists just increase the count
    if (match) {
      match.count += 1;
      return;
    }

    //Push the new item to the cart
    itemToAdd = angular.copy(item);
    itemToAdd.count = 1;

    $scope.cart.push(itemToAdd);
  }

  function getMatchedCartItem(item) {
    /*array.find - Find the shim for it in the demo*/
    return $scope.cart.find(function(itm) {
      return itm.id === item.id
    });

  }

Demo

angular.module('app', []).controller('ctrl', function($scope, items) {
  $scope.items = items;
  $scope.cart = [];

  $scope.deleteItem = function(item) {
    var cart = $scope.cart;
    var match = getMatchedCartItem(item);
    if (match.count > 1) {
      match.count -= 1;
      return;
    }
    cart.splice(cart.indexOf(item), 1);
  }

  $scope.addItem = function(item) {
    var match = getMatchedCartItem(item);
    if (match) {
      match.count += 1;
      return;
    }
    var itemToAdd = angular.copy(item);
    itemToAdd.count = 1;
    $scope.cart.push(itemToAdd);
  }

  function getMatchedCartItem(item) {
    return $scope.cart.find(function(itm) {
      return itm.id === item.id
    });

  }

}).factory("items", function() {
  var items = {};
  items.data = [{
    id: 1,
    title: "Item 1",
    image: "img/item01.jpg"
  }, {
    id: 2,
    title: "Item 2",
    image: "img/item02.jpg"
  }, {
    id: 3,
    title: "Item 3",
    image: "img/item03.jpg"
  }, {
    id: 4,
    title: "Item 4",
    image: "img/item04.jpg"
  }];
  return items;
});

if (!Array.prototype.find) {
  Array.prototype.find = function(predicate) {
    if (this == null) {
      throw new TypeError('Array.prototype.find called on null or undefined');
    }
    if (typeof predicate !== 'function') {
      throw new TypeError('predicate must be a function');
    }
    var list = Object(this);
    var length = list.length >>> 0;
    var thisArg = arguments[1];
    var value;

    for (var i = 0; i < length; i++) {
      value = list[i];
      if (predicate.call(thisArg, value, i, list)) {
        return value;
      }
    }
    return undefined;
  };
}
<script src="https://ajax.googleapis./ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
  <ul>
    <li ng-repeat="item in items.data" id="item{{item.id}}">
      <a href="#">{{item.title}}</a> 
      <img ng-src="{{ item.image }}" />
      <button ng-click="addItem(item)">Add Me</button>
    </li>
  </ul>
  <p>Cart:</p>
  <ul>
    <li ng-repeat="item in cart">
      <a href="#">{{item.title}} | Count: {{item.count}}</a> 
      <a ng-click="deleteItem(item)" class="delete-item">X</a>

    </li>
  </ul>
</div>

I am using Array.prototype.find, you would need to add the shim (as mentioned in the demo) to be able to make it work for non supported browsers.

I'm trying to achieve an array with items that displays as a title and image and when the user click the title the item should be added to a div. However, I can´t make it to work as when I click on "Add me", there is only a blank item added, with no image and no title. I got the delete-function to work but not the add-function.

Here is what I got: The "Add me"-button and the list of items

    <li ng-repeat="item in items.data">
        <a href="#">{{item.title}}</a> <img ng-src="{{ item.image }}" /><a ng-click="deleteItem($index)" class="delete-item">x</a>
        <button ng-click="addItem()">Add Me</button>
    </li>

The array

var myApp = angular.module("myApp", []);
myApp.factory("items", function () {
var items = {};
items.data = [{
    title: "Item 1",
    image: "img/item01.jpg"
}, {
    title: "Item 2",
    image: "img/item02.jpg"
}, {
    title: "Item 3",
    image: "img/item03.jpg"
}, {
    title: "Item 4",
    image: "img/item04.jpg"
}];
  return items;
});

And the functions for add and delete

function ItemsController($scope, items) {
$scope.items = items;

$scope.deleteItem = function (index) {
    items.data.splice(index, 1);
}
$scope.addItem = function () {
    items.data.push({
        title: $scope.items.title
    });
 }
}

I'm trying to achieve an array with items that displays as a title and image and when the user click the title the item should be added to a div. However, I can´t make it to work as when I click on "Add me", there is only a blank item added, with no image and no title. I got the delete-function to work but not the add-function.

Here is what I got: The "Add me"-button and the list of items

    <li ng-repeat="item in items.data">
        <a href="#">{{item.title}}</a> <img ng-src="{{ item.image }}" /><a ng-click="deleteItem($index)" class="delete-item">x</a>
        <button ng-click="addItem()">Add Me</button>
    </li>

The array

var myApp = angular.module("myApp", []);
myApp.factory("items", function () {
var items = {};
items.data = [{
    title: "Item 1",
    image: "img/item01.jpg"
}, {
    title: "Item 2",
    image: "img/item02.jpg"
}, {
    title: "Item 3",
    image: "img/item03.jpg"
}, {
    title: "Item 4",
    image: "img/item04.jpg"
}];
  return items;
});

And the functions for add and delete

function ItemsController($scope, items) {
$scope.items = items;

$scope.deleteItem = function (index) {
    items.data.splice(index, 1);
}
$scope.addItem = function () {
    items.data.push({
        title: $scope.items.title
    });
 }
}
Share Improve this question edited Jan 15, 2015 at 2:58 PSL 124k21 gold badges256 silver badges243 bronze badges asked Jan 14, 2015 at 21:47 pistevwpistevw 4326 silver badges17 bronze badges 3
  • What is $scope.items.title ? – PSL Commented Jan 14, 2015 at 21:50
  • Why is there two add buttons? – Wayne Ellery Commented Jan 14, 2015 at 21:56
  • I tried to use {{item.title}} to display the title from the list, but with no luck. – pistevw Commented Jan 14, 2015 at 21:59
Add a ment  | 

1 Answer 1

Reset to default 4

You need to pass the item under iteration.

<button ng-click="addItem(item)">Add Me</button>

and add the title to the newly added:

  $scope.addItem = function(item) {
    items.data.push({
      title: item.title
    });
  }

it is better not to use $index (it can cause issue when used with filters eg: orderBy filter) instead just pass the item to delete and:

   $scope.deleteItem = function(item) {
     items.data.splice(items.indexOf(item), 1);
   }

You also have an invalid html, li must be a child of ul or ol.

A sample implementation:

 function($scope, items) {
  $scope.items = items;
  $scope.cart = [];

  $scope.deleteItem = function(item) {
    var cart = $scope.cart;
    //Get matched item from the cart
    var match = getMatchedCartItem(item);
    //if more than one match exists just reduce the count
    if (match.count > 1) {
      match.count -= 1;
      return;
    }
    //Remove the item if current count is 1
    cart.splice(cart.indexOf(item), 1);
  }

  $scope.addItem = function(item) {
    //Get matched item from the cart
    var match = getMatchedCartItem(item), itemToAdd ;
     //if item exists just increase the count
    if (match) {
      match.count += 1;
      return;
    }

    //Push the new item to the cart
    itemToAdd = angular.copy(item);
    itemToAdd.count = 1;

    $scope.cart.push(itemToAdd);
  }

  function getMatchedCartItem(item) {
    /*array.find - Find the shim for it in the demo*/
    return $scope.cart.find(function(itm) {
      return itm.id === item.id
    });

  }

Demo

angular.module('app', []).controller('ctrl', function($scope, items) {
  $scope.items = items;
  $scope.cart = [];

  $scope.deleteItem = function(item) {
    var cart = $scope.cart;
    var match = getMatchedCartItem(item);
    if (match.count > 1) {
      match.count -= 1;
      return;
    }
    cart.splice(cart.indexOf(item), 1);
  }

  $scope.addItem = function(item) {
    var match = getMatchedCartItem(item);
    if (match) {
      match.count += 1;
      return;
    }
    var itemToAdd = angular.copy(item);
    itemToAdd.count = 1;
    $scope.cart.push(itemToAdd);
  }

  function getMatchedCartItem(item) {
    return $scope.cart.find(function(itm) {
      return itm.id === item.id
    });

  }

}).factory("items", function() {
  var items = {};
  items.data = [{
    id: 1,
    title: "Item 1",
    image: "img/item01.jpg"
  }, {
    id: 2,
    title: "Item 2",
    image: "img/item02.jpg"
  }, {
    id: 3,
    title: "Item 3",
    image: "img/item03.jpg"
  }, {
    id: 4,
    title: "Item 4",
    image: "img/item04.jpg"
  }];
  return items;
});

if (!Array.prototype.find) {
  Array.prototype.find = function(predicate) {
    if (this == null) {
      throw new TypeError('Array.prototype.find called on null or undefined');
    }
    if (typeof predicate !== 'function') {
      throw new TypeError('predicate must be a function');
    }
    var list = Object(this);
    var length = list.length >>> 0;
    var thisArg = arguments[1];
    var value;

    for (var i = 0; i < length; i++) {
      value = list[i];
      if (predicate.call(thisArg, value, i, list)) {
        return value;
      }
    }
    return undefined;
  };
}
<script src="https://ajax.googleapis./ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
  <ul>
    <li ng-repeat="item in items.data" id="item{{item.id}}">
      <a href="#">{{item.title}}</a> 
      <img ng-src="{{ item.image }}" />
      <button ng-click="addItem(item)">Add Me</button>
    </li>
  </ul>
  <p>Cart:</p>
  <ul>
    <li ng-repeat="item in cart">
      <a href="#">{{item.title}} | Count: {{item.count}}</a> 
      <a ng-click="deleteItem(item)" class="delete-item">X</a>

    </li>
  </ul>
</div>

I am using Array.prototype.find, you would need to add the shim (as mentioned in the demo) to be able to make it work for non supported browsers.

本文标签: