将一个ng控制器分配给两个不工作的元件

时间:2015-01-18 04:17:02

标签: angularjs angularjs-directive

我是angularjs的新手,我来到了非常有趣的oroblem:

我有以下代码:

<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 =&#34; table&#34;在控制按钮和表格的主体中,按下按钮后,行将被添加到表格中,但我想要上面的版本如下:

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

正如你所看到的一切都是一样但只是我们有表和div的ng-controller =表,代码在页面加载时工作,但是当你点击按钮后没有任何反应,这里是代码的链接:

not working version

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

2 个答案:

答案 0 :(得分:1)

您的代码正常运行。控制器不是单例,您只需创建两个控制器和两个范围。将值更新为一个不会影响另一个。您需要创建一个单例来保存值;在角度世界中,最好使用.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);
  }
})

关于您的示例,我只需将整个表及其控件包装在一个HTML元素和一个Controller中。虽然我给的那个插件解释了如何在两个控制器之间进行通信。

答案 1 :(得分:1)

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

当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

  

当Controller通过ng-controller连接到DOM时   指令,Angular将使用。实例化一个新的Controller对象   指定Controller的构造函数。一个新的子范围将是   可用作Controller的构造函数的可注入参数   作为$ scope。

     

使用控制器:

     
      
  1. 设置$ scope对象的初始状态。
  2.   
  3. 添加行为   $ scope对象。
  4.         

    请勿使用控制器:

         
        
    1. 操纵DOM - 控制器应仅包含业务逻辑。   将任何表示逻辑放入控制器会显着影响   它的可测试性。 Angular对大多数情况和指令都有数据绑定   封装手动DOM操作。
    2.   
    3. 格式输入 - 改为使用角度形式控件。
    4.   
    5. 滤镜输出 - 改为使用角度滤镜。
    6.   
    7. 跨控制器共享代码或状态 - 改为使用角度服务。
    8.   
    9. 管理其他组件的生命周期(例如,创建   服务实例)。
    10.   

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

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