将一个 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>
完整版代码运行良好如下:
如您所见,正文中只有一个 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 代码:
我不知道为什么第二个版本不工作,实际上我需要第二个版本工作谁能帮我?
您的代码正在运行。控制器不是单例,您只是创建了两个控制器和两个作用域。更新一个中的值不会影响另一个。您将需要创建一个单例来保存这些值;在 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:
- Set up the initial state of the $scope object.
- Add behavior to the
$scope object.
Do not use controllers to:
- 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.
- Format input — Use angular form controls instead.
- Filter output — Use angular filters instead.
- Share code or state across controllers — Use angular services instead.
- 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>
我是 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>
完整版代码运行良好如下:
如您所见,正文中只有一个 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 代码:
我不知道为什么第二个版本不工作,实际上我需要第二个版本工作谁能帮我?
您的代码正在运行。控制器不是单例,您只是创建了两个控制器和两个作用域。更新一个中的值不会影响另一个。您将需要创建一个单例来保存这些值;在 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:
- Set up the initial state of the $scope object.
- Add behavior to the $scope object.
Do not use controllers to:
- 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.
- Format input — Use angular form controls instead.
- Filter output — Use angular filters instead.
- Share code or state across controllers — Use angular services instead.
- 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>