12

我在页面上有以下 HTML:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" ng-app="myCart">
<head>
    <title>AngularJS Shopping Cart</title>
    <link href="css/jsonstore.css" rel="stylesheet" />
</head>
<body>
    <div id="container">
        <div id="header">
            <h1>The JSON Store</h1>
            <div class="cart-info">
                My Cart (<span class="cart-items">{{item.basketCount}}</span> items)
            </div>
        </div>
        <div id="main" ng-view>
        </div>
    </div>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.4/angular.js"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.4/angular-resource.js"></script>
    <script src="js/routing.js"></script>
    <script src="js/dataresource.js"></script>
    <script src="js/basketinfo.js"></script>
    <script src="js/index.js"></script>
    <script src="js/detail.js"></script>
</body>
</html>

div“main”被我的路由替换为 HTML 模板,但是我想用购物篮计数更新标题部分。

我已经尝试了模型绑定它,如 HTML 和下面所示:

function DetailController($scope, item, basketDetail) {
    $scope.item = item;
    $scope.item.basketCount = basketDetail.getCount();

    //more code
}

我也尝试过注入服务并从 HTML 中调用它。两种方式都不做任何事情。

有人可以帮忙吗?

谢谢

4

3 回答 3

15

您的headerdiv 确实是一个视图,就像您为使用 ng-view 定义的其他视图一样。有一天,您可能希望在该标题视图中显示的不仅仅是一个 basketCount 模型。但是,您甚至将一个模型数据投影到该标题部分这一事实使该部分成为一个视图。所以,我建议给它自己的 $scope 来投影该模型,因此它有自己的控制器。

那么剩下的就是将 basketCount 模型放在哪里?而且我们必须考虑到多个视图可能允许用户做一些需要影响该模型的事情。Angular 对“许多需要访问”的正常回答是依赖注入。因此,我会将 basketCount 模型放入服务中。需要访问它的视图/控制器可以注入它。有一天,您的应用程序可能具有不需要访问这些模型的其他视图,因此这些视图不会注入服务。

潜在地,整个篮子可以在此服务中建模:

app.factory('basketService', function() {
   return {
     items: [],
     itemCount: 0,
     ...
   }
});


function HeaderCtrl($scope, basketService) {
   $scope.basket = basketService;
   ...
}

function DetailCtrl($scope, basketService) {
   $scope.basket = basketService;
   ...
}

<div id="header" ng-controller="HeaderCtrl">
   <h1>The JSON Store</h1>
   <div class="cart-info">
        My Cart (<span class="cart-items">{{basket.itemCount}}</span> items)
   </div>
于 2013-01-31T05:30:30.747 回答
3

你需要注入 $rootScope,然后更新它:

function DetailController($scope, $rootScope, basketDetail) {
    $rootScope.item = $rootScope.item || {};
    $rootScope.item.basketCount = basketDetail.getCount();

    //more code
}

有很多方法可以做到这一点,但这是我的第一个建议,因为它可能是最简单的。


编辑:根据您的要求,其他方法可以做到这一点......

您可以使用 $parent 推送到您的父范围。好处是它非常快速和干净......缺点是它有点草率,因为你的一个控制器在某种程度上假设它的父级是什么(但这仍然不可怕,真的):

   {{item.basketCount}}
   <div ng-controller="InnerCtrl">
   </div>


function InnerCtrl($scope, basketDetail) {
   $scope.$parent.item = $scope.$parent.item || {};
   $scope.$parent.item.basketCount = basketDetail.getCount();
}

然后是上面提到的方法@asgoth,您可以在其中使用嵌套控制器和父范围上的方法来更新父范围。有效,但就像我在“其他方法”部分中的其他解决方案一样,它依赖于对控制器容器的假设,它还依赖于您创建一个额外的控制器。

最后,您可以创建一个服务。现在服务通常不以这种方式使用,但您可以以这种方式使用一种.. 您可以在哪里获取您的 basketDetail 服务,并使用它来来回传递值。像这样:

app.factory('basketDetail', function() {
   return {
      items: { basketCount: 0 },
      getCount: function() {
          //return something here
          return 123;
      }
   }
});


function FooCtrl($scope, basketDetail) {
   $scope.items = basketDetail.items;
   $scope.items.basketCount = basketDetail.getCount();
}

function BarCtrl($scope, basketDetail) {
   $scope.items = basketDetail.items;
}


<div ng-controller="FooCtrl">
  {{items.basketCount}}
</div>
<div ng-controller="BarCtrl">
  {{items.basketCount}}
</div>

之所以可行,是因为两个控制器中的 $scope 都保留了对同一对象的引用,该对象由您的 basketDetail 服务维护。但同样,这并不是真正推荐的方式。

所有这一切都表明:$rootScope,IMO 很可能是您正在寻找的东西。

  • 它不需要创建额外的控制器。
  • 它不需要创建任何额外的函数引用。
  • 不会导致创建任何额外的父/子范围嵌套和后续监视。
于 2013-01-30T16:06:19.117 回答
2

没有真正的需要$rootScope。创建一个父控制器(例如RootController),其范围内有一个函数。子作用域将自动继承它:

<div id="container" ng-controller="RootController">
...


function RootController($scope) {
   $scope.item = {};

   $scope.setBasketCount = function (detail) {
      $scope.item.basketCount = detail.getCount();
   }
}

在您的详细控制器中,您只需使用以下setBasketCount()功能:

function DetailController($scope, item, basketDetail) {
    $scope.item = item;
    $scope.setBasketCount(basketDetail);

    //more code
}
于 2013-01-30T18:06:45.303 回答