AngularJS 视图的路由问题

AngularJS Routing problems with view

我正在尝试创建一个包含商店列表的单页应用程序,在每张商店卡片中都是 link 到另一个包含 table 产品的视图。

商店看起来像:

shop = {
  id: 1,
  name: "foo",
  description: 'bar',
  products: [item1, itemn];
};

app.js:

angular
  .module('lightpointTestApp', [
    'ngCookies',
    'ngRoute',
    'ui.sortable'
  ])
  .config(function ($routeProvider) {
    $routeProvider
      .when('/', {
        templateUrl: 'views/main.html',
        controller: 'MainCtrl'
      })
      .when('/about', {
        templateUrl: 'views/about.html',
        controller: 'AboutCtrl'
      })
      .when('/products/:shopID', {
        templateUrl: 'views/products.html',
        controller: 'ProductsCtrl'
      })
      .otherwise({
        redirectTo: '/'
      });
  });

Main.html 查看商店列表在哪里:

<h3>Shop list</h3>
<div class="row shopsContainer" ui-sortable ng-model="shops">

  <div class="col-lg-3 shopCard" ng-repeat="shop in shops">
    <button class="btn close cardClose" ng-click="removeShop($index)">&times;</button>
    <div class="cardNumber">{{ shops.indexOf(shop) + 1 }}</div>
    <div class="cardHeader">{{ shop.name }}</div>
    <div class="cardBody">
      {{ shop.address }}<br />
      {{ shop.hours }}<br />      
      <a href="/#/products/{{ shop.id }}">View {{ shop.products.length }} products</a>
    </div>
  </div>

</div>
<div class="row">
  <input type="text" ng-model="newShop.name" placeholder="Shop name" class="col-lg-3" />
  <input type="text" ng-model="newShop.address" placeholder="Shop address" class="col-lg-3" />
  <input type="text" ng-model="newShop.hours" placeholder="Shop hours" class="col-lg-3" />
  <button class="btn btn-primary col-lg-3" type="button" ng-disabled="!newShop.name || !newShop.address || !newShop.hours" ng-click="addShop()">Add Shop</button>
</div>

</span>
</div>
</div>

products.js - 产品页面控制器

angular.module('lightpointTestApp')
  .controller('ProductsCtrl', function ($scope, $routeParams, shops) {
    $scope.shopList = shops;
    $scope.shop = {};

    $scope.getShop = function (id) {
      for (var i = 0; i < $scope.shopList.length; i++) {
        if ($scope.shopList[i].id === id) {
          return $scope.shopList[i];
        }
      }
      return null;
    };

    var shopID = $routeParams.shopID;
    $scope.shop = $scope.getShop(shopID);

  })

products.html 产品 table 在哪里

<h2>{{ shop.name }}</h2>
  <table class="table table-hover">
    <tr>
      <th>Product Name</th>
      <th>Product Description</th>
    </tr>
    <tr ng-repeat="product in shop.products">
     <td> {{ product.name }} </td>
     <td> {{ product.description }} </td>      
    </tr>
  </table>

问题是 products.html 不与 products.js 绑定并显示类似 {{shop.name}} 和空的 table.

P.S。我认为 products.js 不正确,但我已尽一切努力做好。

谢谢。

您在 ProductsCtrl 中有一个参数 shops,但没有任何东西可以为其传递值,因此它将是 null。你给它设置 $scope.shopList 的值,然后尝试遍历一个 NULL 数组,所以你得到一个异常。

您可以将 shops 的值存储在服务中,然后通过注入将它们传递给您的应用程序。您可以在 main.js 或服务本身内初始化它们的值,然后如果将它们注入 ProductsCtrl,这些值将可用,例如

angular.module('lightpointTestApp')
      .controller('ProductsCtrl', ['$scope', '$routeParams', 'shopsService', 
         function ($scope, $routeParams, shopsService) {
             $scope.shopList = shopService;
             $scope.shop = {};

             $scope.getShop = function (id) {

                for (var i = 0; i < $scope.shopList.length; i++) {
                  if ($scope.shopList[i].id === id) {
                     return $scope.shopList[i];
                  }
                }
                return null;
             };

            var shopID = $routeParams.shopID;
            $scope.shop = $scope.getShop(shopID);

        }]);

shopsService 可能类似于

angular.module('lightpointTestApp')
   .service('shopsService', function() {
       return [ 
                // add whatever fields you need here from code in main.js
                { name: 'shop1', address: 'addr1' },
                { name: 'shop2', address: 'addr2' }
              ];
   });

您的商店物品来自哪里?您正在 products.js 中传递商店,但未在代码中引用它。您还应该使用 $q 来使用异步数据的承诺。还可以使用 filter() 函数而不是 for 循环来按 shopId 查找商店。

您现在是在商店里 API 购物还是在当地 json 购物? 使用 angular,您应该在工厂或服务中分离数据逻辑操作:

productService.js

angular.module('lightpointTestApp')
  .factory('shopService',function($http, $q){
    var shops = [];
    return {
      getShops: function () {
        var deferred = $q.defer();
        $http.get('<path to product.json or api>').success(function(data){
          shops = data;
          deferred.resolve(data);
        }) 
        return deferred.promise;
      },
      getShopById: function(shopID) {
        var deferred = $q.defer();
        deferred.resolve(shops.filter(function(chain){
          return chain.id === shopID;
        })[0]);
        return deferred.promise;
      }
    } 
  });

product.js

angular.module('lightpointTestApp')
 .controller('ProductsCtrl', function ($scope, $routeParams, $q,shopService) {
    $scope.shopList = [];
    $scope.shop = {};
    var shopID = $routeParams.shopID;

    shopService.getShops.then(function(shops){
      $scope.shopList = data;    
    })

    $scope.getShopById = function(shopID) {
      shopService.getShopById(shopID).then(function(shop){
      $scope.shop = shop;
     });
    }
  });