ng-repeat中的ng-model - 初始化唯一范围属性

时间:2016-05-12 23:09:16

标签: javascript angularjs

我正在创建一个角度为1.5.x的购物车,我真的很想专注于做正确的'Angular Way'。我有一个产品清单(ng-repeat),用户可以在其中调整任何商品的数量(ng-model),然后将该商品(及相关数量)添加到购物车(ng-click) 。

我遇到的问题是在数量输入中分配给ng-model的变量。我不想更新ctrl.productList数组,所以我想我会创建一个单独的ctrl.itemQuantity基元。但是,使用ng-repeat时,每个输入框都会在更改一个输入框时发生更改。

我目前的解决方案是使用html中的$index中的ng-model初始化具有动态名称的新原始属性(但不在控制器中初始化它)。

这很好用,但看起来有点hacky,输入都是空白而不是0,因为ng-model开始未定义。如果这是真正的方法,我想我可以通过在ng-model上运行forEach并将每个变量分配给0来初始化所有ctrl.productsList变量。

有没有人有更好的方法来解决这个问题?这似乎是一种相当普遍的情况。

标记:

<div class="section-container product-container">
        <div class="section-header product" ng-repeat="product in products.productList">
            <div class="product-info">
                <div>{{ product.name }} - <span>{{ product.price | currency }}</span></div>
                <div><a href="">{{ product.brand }}</a></div>
            </div>
            <div class="product-selection">
                <label for="product-quantity-{{$index}}">Quantity: </label>
                //Initialize new dynamically named ng-model for each quantity input
                <input id="product-quantity-{{$index}}" type="number" ng-model="products['quantity-' + $index]">
                <a href="" class="product-cart-btn" ng-click="products.addCart(product, $index)">+</a>
            </div>

        </div>
    </div>

控制器:

function ProductsController() {
  var ctrl = this;

  //Cart
  ctrl.cartList = [];
  ctrl.addCart = function(product, index){
    if(ctrl.cartList.indexOf(product) === -1){
      ctrl.errorMessage = '';
      console.log(ctrl);
      //Add input value here
      product.quantity = ctrl['quantity-'+index];
      ctrl.cartList.push(product);

      //Reset input value
      ctrl['quantity-'+index]=0;
    }else{
      ctrl.errorMessage = "Your cart already contains " + product.name + " by " + product.brand +
      ". Please visit your cart to adjust item quantities.";
    }
  };


  //Products
  ctrl.productList = [
    {
      name: 'Tissue (50 Ct)',
      brand: 'Kleenex',
      price: '5.00'
    }, {
      name: 'Whole Wheat Bread',
      brand: 'Roman Meal',
      price: '3.27'
    }, {
      name: 'Chili Spiced Mango',
      brand: "Trader Joe's",
      price: '4.56'
    }
  ];
}

如果我需要进一步解释,请告诉我。干杯!

2 个答案:

答案 0 :(得分:1)

创建产品选择器指令以包装产品

如果您使用transclude实现它,它可能如下所示:

Dim WebServiceObj As Object
dim IisSiteId as Integer = 0
WebServiceObj = GetObject("IIS://localhost/W3SVC/" & IisSiteId)
WebServiceObj.Stop()
WebServiceObj.Start()

否则它可能如下所示:

<div class="section-container product-container">
  <div class="section-header product" ng-repeat="product in products.productList">
        <div class="product-info">
          <div>{{ product.name }} - <span>{{ product.price | currency }}</span></div>
          <div><a href="">{{ product.brand }}</a></div>
        </div>
      <product-selector product="product" on-product-selected="addCart">
        <div class="product-selection">
          <label for="product-quantity-{{$index}}">Quantity: </label>
          //Initialize new dynamically named ng-model for each quantity input
          <input id="product-quantity-{{$index}}" type="number" ng-model="quantity">
          <a href="" class="product-cart-btn" ng-click="FireProductSelected(product, quantity)">+</a>
        </div>
      </product-selector>
  </div>
</div>

答案 1 :(得分:0)

我不知道这是一个很好的做法,但由于ng-repeats会生成自己的私有作用域,因此您实际上可以在输入标记中生成作用域变量。如果你希望它默认显示为“0”,你可以使用ng-init将它设置为0(再次,可能不是最干净的)。

<input id="product-quantity-{{$index}}" type="number" ng-model="quantity" ng-init="quantity = 0;" />
<a href="" class="product-cart-btn" ng-click="products.addCart(product, quantity)">+</a>

那应该是诀窍,我会让你决定它是否不那么狡猾;)