Squeak.ru - шаблоны программирования

Добавление и удаление элементов из ng-repeat, простая реализация корзины с использованием angular

Я пытаюсь получить массив с элементами, которые отображаются как заголовок и изображение, и когда пользователь щелкает заголовок, элемент должен быть добавлен в div. Однако я не могу заставить его работать, так как когда я нажимаю «Добавить меня», добавляется только пустой элемент, без изображения и без названия. У меня работает функция удаления, но не функция добавления.

Вот что у меня получилось: Кнопка "Добавить меня" и список предметов

    <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>

Массив

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;
});

И функции для добавления и удаления

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
    });
 }
}

  • Что такое $scope.items.title? 15.01.2015
  • Почему две кнопки добавить? 15.01.2015
  • Я пытался использовать {{item.title}} для отображения заголовка из списка, но безуспешно. 15.01.2015

Ответы:


1

Вам нужно передать элемент в итерацию.

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

и добавьте заголовок к вновь добавленному:

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

лучше не использовать $index (это может вызвать проблемы при использовании с фильтрами, например: фильтр orderBy), вместо этого просто передайте элемент для удаления и:

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

У вас также недопустимый HTML-код, li должен быть дочерним элементом ul или ol.

Пример реализации:

 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
    });

  }

Демо

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.com/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>

Я использую Array.prototype.find вам нужно будет добавить прокладку (как указано в демо), чтобы она работала для неподдерживаемых браузеров.

14.01.2015
  • Да, это работает! Я думаю, что понимаю изменения, я чувствовал, что близок к решению :) Большое спасибо за вашу помощь! 15.01.2015
  • @jodor я добавил объяснение, смотрите мое обновление ответа. Также я использую array.find. 15.01.2015
  • @PSL, не могли бы вы добавить код для расчета цены товара на основе количества? Также общая тележка. Спасибо :) 15.11.2015
  • Новые материалы

    Угловая структура архитектуры
    Обратите внимание, что эта статья устарела, я решил создать новую с лучшей структурой и с учетом автономных компонентов: https://medium.com/@marekpanti/angular-standalone-architecture-b645edd0d54a..

    «Данные, которые большинство людей используют для обучения своих моделей искусственного интеллекта, поставляются со встроенным…
    Первоначально опубликовано HalkTalks: https://hacktown.com.br/blog/blog/os-dados-que-a-maioria-das-pessoas-usa-para-treinar-seus-modelos-de-inteligencia-artificial- ja-vem-com-um-vies-embutido/..

    Сильный ИИ против слабого ИИ: различия парадигм искусственного интеллекта
    В последние годы изучению и развитию искусственного интеллекта (ИИ) уделяется большое внимание и прогресс. Сильный ИИ и Слабый ИИ — две основные парадигмы в области искусственного интеллекта...

    Правильный способ добавить Firebase в ваш проект React с помощью React Hooks
    React + Firebase - это мощная комбинация для быстрого и безопасного создания приложений, от проверки концепции до массового производства. Раньше (знаете, несколько месяцев назад) добавление..

    Создайте API с помощью Python FastAPI
    Создание API с помощью Python становится очень простым при использовании пакета FastAPI. После установки и импорта вы можете создать приложение FastAPI и указать несколько конечных точек. Каждой..

    Веселье с прокси-сервером JavaScript
    Прокси-серверы JavaScript — это чистый сахар, если вы хотите создать некоторую общую логику в своих приложениях, чтобы облегчить себе жизнь. Вот один пример: Связь клиент-сервер Мы..

    Получить бесплатный хостинг для разработчиков | Разместите свой сайт за несколько шагов 🔥
    Статические веб-сайты — это веб-страницы с фиксированным содержанием и его постоянным содержанием. Но теперь статические сайты также обрабатывают динамические данные с помощью API и запросов...