将一个 ng-controller 分配给两个不工作的元素

assigning one ng-controller to two element not working

我是 angularjs 的新手,我遇到了一个非常有趣的问题:

我有以下代码:

<body ng-app="app" ng-controller="table">
<div id="clcikbtn"
    style="background-color: black; width: 20px; height: 20px;"
    ng-click="addTable()"></div>
<table class="table table-hover">
    <thead>
        <tr>
            <th>item</th>
            <th>price</th>
            <th>number</th>
            <th>edit</th>
        </tr>
    </thead>
    <tbody>
        <tr ng-repeat="x in typesHash">
            <td>{{x.name}}</td>
            <td>{{x.price}}</td>
            <td>{{x.unit}}</td>
            <td>edit</td>
        </tr>
    </tbody>
</table>

完整版代码运行良好如下:

working version

如您所见,正文中只有一个 ng-controller="table" 控制按钮和 table 并且在点击按钮后,一行将添加到 table 但我想要上面的版本如下:

<body ng-app="app">
<div id="clcikbtn"
    style="background-color: black; width: 20px; height: 20px;"
    ng-controller="table" ng-click="addTable()"></div>
<table class="table table-hover" ng-controller="table">
    <thead>
        <tr>
            <th>item</th>
            <th>price</th>
            <th>number</th>
            <th>edit</th>
        </tr>
    </thead>
    <tbody>
        <tr ng-repeat="x in typesHash">
            <td>{{x.name}}</td>
            <td>{{x.price}}</td>
            <td>{{x.unit}}</td>
            <td>edit</td>
        </tr>
    </tbody>
</table>

如您所见,一切都是一样的,只是我们为 table 和 div 设置了 ng-controller=table 并且代码在页面加载时有效,但之后当你点击按钮时没有任何反应,这里是 link 代码:

not working version

我不知道为什么第二个版本不工作,实际上我需要第二个版本工作谁能帮我?

您的代码正在运行。控制器不是单例,您只是创建了两个控制器和两个作用域。更新一个中的值不会影响另一个。您将需要创建一个单例来保存这些值;在 angular 世界中,最好使用 .factory().

编辑

This plunker 显示了一个完整的示例,其中包含一些代码样式改进;)

工厂可能看起来像这样:

.factory('tableService', function () {
  var dataContainer = [{
    name: 'sugar',
    price: 1,
    unit: 1
  }, {
    name: 'lemon',
    price: 100,
    unit: 2.5
  }];
  var service = {
    data: data,
    add: add
  };
  return service;
  function data() {
    return dataContainer;
  }
  function add(data) {
    dataContainer.push(data);
  }
})

关于您的示例,我只是简单地将整个 table 及其控件包装在一个 HTML 元素和一个控制器中。尽管我给出的 plunker 解释了如何在两个控制器之间进行通信。

您的第二个版本存在一些问题(考虑到您要完成的任务)。

当您通过 Angular 注入控制器时,它每次 都会实例化该控制器的一个新实例 。这意味着您的代码实际上使用了 2 个不同的 table 控制器。因此,控制器无法维护实例之间的数据。它们扮演视图模型的角色,并为分配给它的视图维护自己的范围。

为了说明范围,我将您的代码放在以下代码段中并将 ng-controller 上移了一个级别。您可以看到,单击第一个按钮将添加到第一个网格,而第二个按钮将单独添加,反之亦然。

 var app = angular.module('app', []);


 app.controller('table', function($scope) {
   $scope.typesHash = [{
     name: 'sugar',
     price: 1,
     unit: 1
   }, {
     name: 'lemon',
     price: 100,
     unit: 2.5
   }];
   $scope.addTable = function() {
     var arr = {
       name: 'meat',
       price: 200,
       unit: 3.3
     };
     $scope.typesHash.push(arr);
   }
 });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="app">
  <div ng-controller="table">
    <div id="clcikbtn" style="background-color: black; width: 20px; height: 20px;" ng-click="addTable()"></div>
    <table class="table table-hover">
      <thead>
        <tr>
          <th>item</th>
          <th>price</th>
          <th>number</th>
          <th>edit</th>
        </tr>
      </thead>
      <tbody>
        <tr ng-repeat="x in typesHash">
          <td>{{x.name}}</td>
          <td>{{x.price}}</td>
          <td>{{x.unit}}</td>
          <td>edit</td>
        </tr>
      </tbody>
    </table>
  </div>
  <hr/>
  <div ng-controller="table">
    <div id="clcikbtn" style="background-color: black; width: 20px; height: 20px;" ng-click="addTable()"></div>
    <table class="table table-hover">
      <thead>
        <tr>
          <th>item</th>
          <th>price</th>
          <th>number</th>
          <th>edit</th>
        </tr>
      </thead>
      <tbody>
        <tr ng-repeat="x in typesHash">
          <td>{{x.name}}</td>
          <td>{{x.price}}</td>
          <td>{{x.unit}}</td>
          <td>edit</td>
        </tr>
      </tbody>
    </table>
  </div>
</body>

请参阅 Angular 文档:https://docs.angularjs.org/guide/controller

When a Controller is attached to the DOM via the ng-controller directive, Angular will instantiate a new Controller object, using the specified Controller's constructor function. A new child scope will be available as an injectable parameter to the Controller's constructor function as $scope.

Use controllers to:

  1. Set up the initial state of the $scope object.
  2. Add behavior to the $scope object.

Do not use controllers to:

  1. Manipulate DOM — Controllers should contain only business logic. Putting any presentation logic into Controllers significantly affects its testability. Angular has databinding for most cases and directives to encapsulate manual DOM manipulation.
  2. Format input — Use angular form controls instead.
  3. Filter output — Use angular filters instead.
  4. Share code or state across controllers — Use angular services instead.
  5. Manage the life-cycle of other components (for example, to create service instances).

出于这些原因,我建议对整组元素使用相同的控制器,如下所示:

<body ng-app="app">
  <div ng-controller="table">
    <div id="clcikbtn" style="background-color: black; width: 20px; height: 20px;" ng-click="addTable()"></div>
    <table class="table table-hover">
      <thead>
        <tr>
          <th>item</th>
          <th>price</th>
          <th>number</th>
          <th>edit</th>
        </tr>
      </thead>
      <tbody>
        <tr ng-repeat="x in typesHash">
          <td>{{x.name}}</td>
          <td>{{x.price}}</td>
          <td>{{x.unit}}</td>
          <td>edit</td>
        </tr>
      </tbody>
    </table>
  </div>
</body>