提供AngularJS控制器数据

时间:2013-12-04 03:41:26

标签: javascript angularjs

假设控制器可以操作示波器上的某些数据,那么为控制器提供该数据的最佳做法是什么?

例如,如果我有一个项目列表,我可能想要一个ListController来操作列表,而一个ItemController来操作一个单独的项目。但是如何为每个ItemController提供一个项目?

在下面的例子中,doSomethingToItem将如何访问该项目。当嵌套在ngRepeat中时,该项为$ scope.item,但在选择视图中,我们要操作的项是$ scope.selection。

angular.module('MyApp', [])

    .controller('ListController', function($scope, $http) {

        $scope.list = $http.get(...);

        $scope.selection = null;

    })

    .controller('ItemController', function($scope) {

        $scope.doSomethingToItem = function() {
            ...
        };

    })


<div ng-controller="ListController">
    <div ng-repeat="item in list" ng-click="selection = item">
        <div ng-controller="ItemController">
            <button ng-click="doSomethingToItem()">Do Something</button>
        </div>
    </div>
    <div ng-show="selection"
        <div ng-controller="ItemController">
            <button ng-click="doSomethingToItem()">Do Something</button>
        </div>
    </div>
</div>

这不是一个共同的结构,还是我的倒退思路?

2 个答案:

答案 0 :(得分:2)

你应该明白Angular会在你的情况下创建n + 1 ItemController。 N表示项目,1表示选择部分。

要更轻松地传递需要处理的对象,可以将方法签名更改为

doSomethingToItem(item)并在html中执行

<button ng-click="doSomethingToItem(item)">Do Something</button>两个地方。

或者对于重复的情况,item变量包含您可以在ItemController中访问的对象

selection变量包含对select控制器的引用,可以从选择部分下定义的控制器实例引用。

更新:ng-repeat和选择中的表达式会有所不同

<button ng-click="doSomethingToItem(item)">Do Something</button>

 <div ng-show="selection"
        <div ng-controller="ItemController">
            <button ng-click="doSomethingToItem(selection)">Do Something</button>
        </div>
    </div>

答案 1 :(得分:1)

您可以像这样传递项目数据模型:

<div ng-init="instance = item" ng-controller="ItemController">
</div>

“instance”将引用“ListController”中的列表数组数据模型项。

你可以在ItemController函数闭包中访问它的属性:

.controller("ItemController", function($scope){
  $scope.instance={};
  $scope.doSomething = function(){
    console.log($scope.instance.name);
  }
  $scope.$watch('instance',function(){
    console.log("iitem changed");
  },true);
});

我不太确定您希望在“选择”实施中实现什么功能。

我认为您希望实现所选列表,并且当用户单击列表项时,将向其添加列表项。如果要将所选项目添加到列表中,可以尝试创建“选定列表”模型来控制所选列表视图。

ListController.js

.controller("ListController", function($scope){
  $scope.selectedList = [];
  $scope.addItem = function(item){
    $scope.selectedList.push(item);
  }
});

HTML

<div ng-repeat="selected in selectedList">
  <div ng-init="instance = selected" ng-controller="ItemController">
    <span>{{instance.name}}</span>
    <button ng-click="doSomething()">selectedAction</button>
  </div>
</div>

我写了一个简单的多选列表示例如下:

<强> HTML

<!doctype html>
<html lang="en" ng-app="myApp">
<head>
<meta charset="UTF-8">
<title>Nested controller</title>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.min.js"></script>
<script src="js/nestedController.js"></script>
</head>
<body>
<div ng-controller="parentCtrl">
    <h2>List</h2>
    <div ng-repeat="item in list">
        <input type="checkbox" ng-model="item.selected" ng-checked="item.selected"/>
        <div ng-init="instance = item" ng-controller="childCtrl">
            <span>{{instance.name}}</span>
            <button ng-click="doSomething()">doSomething</button>
        </div>          
    </div>
    <h2>Selected</h2>
    <div ng-repeat="selected in selectedList">
        <div ng-init="instance = selected" ng-controller="childCtrl">
            <span>{{instance.name}}</span>
            <button ng-click="selectedAction()">selectedAction</button>
        </div>
    </div>
</div>

<强> JS

angular.module("myApp",[])
.controller("parentCtrl",function($scope){
  //test data
  $scope.list = [{name:'item1',age:'12',selected:false},{name:'item2',age:'18',selected:false}];
  //use model to control selected list view
  $scope.selectedList = [];
  //refresh the selected list model when the list checked stauts has been updated
  $scope.$watch('list',function(){
    console.log("parent controller detected change");
    $scope.selectedList = [];
    $scope.list.forEach(function(elem,index,array){
        if(elem.selected===true){
            $scope.selectedList.push(elem);
        }
    });
  },true);
})
.controller("childCtrl",function($scope){
  $scope.instance={}
  $scope.doSomething = function(){
    alert("I'm the item: "+$scope.instance.name);
  }

  $scope.selectedAction = function(){
    alert("I'm the selected item: "+$scope.instance.name);
  }
  //could register a watcher to monitor the model status
  $scope.$watch('instance',function(){
    console.log("child controller detected change");
  },true);
});

以下是jsFiddle demo

希望这有帮助。