2016-02-26 71 views
0

我有,我有angularjs和NG-重复的问题挣扎没有更新,我有被NG-重复生成的表:NG重复

<div> 
    <select ng-model="item" ng-controller="dropdown" 
     ng-change="update(item)"> 
     <option value="volvo">Volvo</option> 
     <option value="saab">Saab</option> 
    </select> 
    <table ng-controller="repeatTest"> 
     <tr> 
      <td>name</td> 
      <td>family name</td> 
      <td>score</td> 
     </tr> 
     <tr ng-repeat="item in list"> 
      <td>{{ item.name }}</td> 
      <td>{{ item.familyName }}</td> 
      <td>{{ item.score }}</td> 

     </tr> 


    </table> 


</div> 

和我的js代码如下:

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

app.service('sharedService', function() { 


    this.list = []; 

}); 
app.controller('dropdown', function($scope, sharedService) { 
$scope.update = function(item) { 
    if (item == "volvo") { 
     sharedService.list = [ { 
      name : 'A', 
      familyName : 'AA', 
      score : '10' 
     }, { 
      name : 'B', 
      familyName : 'BB', 
      score : '5' 
     } ]; 

     $scope.list = sharedService.list; 
     console.log($scope.list); 
    } else { 
     sharedService.list = [ { 
      name : 'zzz', 
      familyName : 'zzz', 
      score : '100' 
     }, { 
      name : 'zz', 
      familyName : 'zz', 
      score : '70' 
     } ]; 
     $scope.list = sharedService.list; 
    } 
} 

}); 
app.controller('repeatTest', function($scope, sharedService) { 
sharedService.list = [ { 
    name : 'xxx', 
    familyName : 'xxx', 
    score : 'xxx' 
}, { 
    name : 'xx', 
    familyName : 'xx', 
    score : 'xx' 
} ]; 

$scope.list = sharedService.list; 

}); 

现在我的问题是SI在页面加载生成的,当我改变选择框,虽然它应该是因为我绑定表,以列表这是在范围定义不会再更改表和我假设每当范围变化表也应该受到影响。谁能帮忙?

+0

和'ng-controller =“repeatTest”'定义在哪里? –

+0

@MaciejDobrowolski对不起,我忘记了,请参阅更新 –

回答

2

对于您的示例,您不需要两个控制器。

只需将下拉控制器分配给您的父div并删除repeatTest控制器。事情是这样的:

<div ng-controller="dropdown"> 
    <select ng-model="item" ng-change="update(item)"> 
    <option value="volvo">Volvo</option> 
    <option value="saab">Saab</option> 
    </select> 

    <table> 
    <tr> 
     <td>name</td> 
     <td>family name</td> 
     <td>score</td> 
    </tr> 
    <tr ng-repeat="item in list"> 
     <td>{{ item.name }}</td> 
     <td>{{ item.familyName }}</td> 
     <td>{{ item.score }}</td> 
    </tr> 
    </table> 
</div> 

所以,如果你有同时处理选择和表你不需要观看列表变量在您的服务更改相同的控制器。

你可以用这种方式解决或执行事件,但我认为这是很容易的。

这里正确的代码的jsbin:http://jsbin.com/sivapa/edit?html,js,console,output

+0

谢谢,但这是一个大场景的一个小例子,所以我需要的是用两个控制器来处理这个问题,你知道我的方法为什么不起作用吗? –

+0

是的,您的方法不起作用,因为您需要在其他控制器(您的repeatTest)中观察列表变量的变化。所以,你需要注入$范围和添加后$ scope.list = sharedService.list这一行: '$ scope.watch(函数(){ 回报sharedService.list; },函数(的newval){$ scope.list = newVal; });' 这应该工作;) – eliagentili

+0

我已经更新了演示jsbin更好的解释,这里的链接:[http://jsbin.com/sivapa/edit?html ,js,console,output](http://jsbin.com/sivapa/edit?html,js,console,output) – eliagentili

2

您有两个范围,一个为每个控制器。通过分配$ scope.list,您实际上是通过引用传递给每个控制器的列表。所以,你应该清除并重新创建阵列无需重新分配$scope.listsharedService.list,或者你可以:

两个控制器上添加

$scope.sharedService = sharedService; 

,并使用ng-repeat="item in sharedService.list"相反,你会得到你的更新。

您当前的解决方案无法正常工作的原因是您每次调用update时都会创建一个新阵列。这意味着其他控制器的列表仍然保持对原始/前一个数组的引用。

避免每次创建一个新的数组的例子:

var result = []; 
if (item == "volvo") { 
    result = [ { 
     name : 'A', 
     familyName : 'AA', 
     score : '10' 
    }, { 
     name : 'B', 
     familyName : 'BB', 
     score : '5' 
    } ]; 
} else { 
    result = [ { 
     name : 'zzz', 
     familyName : 'zzz', 
     score : '100' 
    }, { 
     name : 'zz', 
     familyName : 'zz', 
     score : '70' 
    } ]; 
} 

//Clear array 
sharedService.list.splice(0,sharedService.list.length); 
//Copy values from result into existing array 
sharedService.list.push.apply(sharedService.list, result); 

请注意,这是未经测试。而且你还必须在某处执行$ scope.list的初始任务。

+0

如果@Troels是正确的,你也可以使用Array.splice解决这个问题()'替换数组的内容而不是用新数组替换数组。这会导致数组引用保持不变。 –

+0

所以你的意思是这个$ scope.list我更新引用,所以如果我想更新$ scope.list的值,我应该怎么做? –

+0

永远不要在sharedService外设置sharedService.list的值(使用赋值运算符=)。在sharedService中只做一次(就像你已经是这样)。而不是创建一个新的数组,清除现有的并推入新的值。 –

2

'repeatTest'控制器无法知道服务数据已经改变......除非您告诉它注意这一点。试试这个版本控制器:

app.controller('repeatTest', function($scope, sharedService) { 

    $scope.list = sharedService.list; 

    $scope.$watch(function() { 
     return sharedService.list; 
    }, 
    function(o, n) { 
     if (o != n) $scope.list = n 
    }); 
}); 

此外,由于你的下拉控制器不直接影响repeatTest列表中,您不需要在控制器更新$ scope.list:

app.controller('dropdown', function($scope, sharedService) { 
    $scope.update = function(item) { 
    console.log(item); 
    if (item == "volvo") { 
     sharedService.list = [{ 
     name: 'A', 
     familyName: 'AA', 
     score: '10' 
     }, { 
     name: 'B', 
     familyName: 'BB', 
     score: '5' 
     }]; 
    } else { 
     sharedService.list = [{ 
     name: 'BMW', 
     familyName: 'Germany', 
     score: '100' 
     }, { 
     name: 'Frari', 
     familyName: 'America', 
     score: '100' 
     }]; 
    } 
    } 
    // Do a little initialization 
    $scope.item="volvo"; 
    $scope.update($scope.item); 
}); 

这里是一个plunk:http://plnkr.co/edit/42snC2WyfdKfNzrIKA0o

+0

现在感谢我从我在角度学到的东西感到困惑,虽然我是初学者,当我们将变量分配给范围时,它在任何地方都可以访问我是对吗?如果是,那么该变量的任何更新应该对模块可见!你能解释一点吗? –

+0

是的,但是当您致电更新时,您并未更新repeatTest中的$ scope.list。而且,由于您正在更改参考,而不是价值,它不会起作用。如果你对参考价值不够强,请阅读本页:http://docstore.mik.ua/orelly/webprog/jscript/ch04_04.htm –